主题: 为何用自定义的类作hashmap
的key时需要重写hashcode
方法和equals
方法
Object类的中的hashcode方法和equals方法
Java中所有的类都是Object类的子类,Object中自带的hashcode方法,就是通过计算内存地址转换一个整数实现的,是一个native
方法,返回值是int类型:
public native int hashCode();
Object中自带的equals方法,从源码中可以看出,就是将比较与被比较对象用==
进行比较,用的还是比较hash值的方式
public boolean equals(Object obj) {
return (this == obj);
}
重写hashcode
如果不重写hashcode方法,那么即便是两个内容完全相同key对象,每次通过hashcode方法计算出的hash值也都是不一样的,因为是根据其对象所在内存地址计算的,因而做存储时也会被当作时不同的key;
重写hashcode方法该怎么写呢,这没有固定的格式,项目中看到很多中写法,列举两个
-
如果是一个实体类,有唯一的字段id,那么可以利用该字段直接作为其hash值,如下
public class user{ private int id; private String name; @override public int hashcode(){ return this.id; } }
-
也可以是如下写法,因为
String
类中已经重写
了hashcode方法,所以当name
值相同时,其对应hash值一定相同public class User{ private int id; private String name; @override public int hashcode(){ return id*name.hashcode; } }
重写equals方法
equals方法在上面已经介绍过了,其实就是用==进行比较,如果不重写那么即便是两个内容完全相同
的对象,equals方法返回值依然是false
,和hashcode类似也需要进行类似的方法重写:
重写equals方法和hashcode类似,并没有什么固定写法,列举一个目前开发中常用的
-
思路是先使用
instanceof
关键字判断这个被比较对象与对象是否属于一个类,返回值是true的话,再将二者转换成json
字符串,最后通过String已经重写好了的equals方法进行比较,如下:public class User{ private int id; private String name; @override public boolean equals(Object object){ if(object instanceof User){ User compareObj = (User)object; String soureStr = JsonUtils.objectToJson(this); String targetStr = JsonUtils.objectToJson(compareObj); return soureStr.equals(targetStr); } return false; } }
hashmap中使用hashcode和equals方法
举例,将一个对象user对象作为key存入hashmap当中,会经历以下流程,能够看出在判断两个对象是否相等时,要经过以下步骤:
- 是先去判断二者的hash值是否相同,因为计算和比较hash值所耗费代价要远低于通过equals进行比较,所以先比较hash值也可以提高效率;
- 如果比较结果不相等,则直接返回false;
- 如果比较结果相等,则使用equals方法进行比较;
- 如果相等,则返回true,如果不相等,则返回fasle。
总结
在hashmap中,对于两个对象的比较,都充分用到了key对象的hashcode方法和equals方法;
如果不重写hashcode方法,那么即便是两个内容完全一致的key对象,它仍会视为是不同的key,导致数据存取无法进行;
如果不重写equals方法,那么equals方法只是简单的将两个对象进行==比较,实际上也是通过对象间的内存地址进行比较,也导致上述情况的发生。
转载:https://blog.csdn.net/qq_40898875/article/details/117385871