阿里巴巴开发规范
只要重写 equals,就必须重写 hashCode
因为 Set 存储的是不重复的对象,依据 hashCode 和 equals 进行判断,所以 Set 存储的对象必须重写这两个方法
如果自定义对象做为 Map 的键,那么必须重写 hashCode 和 equals
Object作者建议
相同的对象必然是相同的哈希值,不同的哈希值是不同的对象
在开发规范和Object作者建议 中都是只要重写 equals, 就必须重写 hashCode 为什么?
要明白重写equals的原因要先明白equals是什么,与之关联的 ==,hashCode又是什么?
== :是对于基本数据类型的值比较
equals :定义在JDK的Object.java中 这就意味着Java中的任何类都包含有equals()函数
equals
hashCode() 和 equals() 有什么关系?
有关系,但不能说完全有关系 以“类的用途”分2种情况来说明
类对应的散列表(散列表就是同时运用了数组和链表 如 HashMap,HashSet,HashTable等这些本质是散列表的数据结构中)
1 不会创建“类对应的散列表”
在这种情况下,该类的“hashCode() 和 equals() ”是没有任何关系的 equals() 用来比较该类的两个对象是否相等,而hashCode() 则根本没有任何作用
可以看到equals是相等的,但hashCode值是不同的,在这种情况下hashCode值是没有任何作用的
2 会创建“类对应的散列表”
在这种情况下,该类的“hashCode() 和 equals() ”是有关系的: 如果两个对象相等,那么它们的hashCode()值一定相同。
这里的相等是指,通过equals()比较两个对象时返回true。
如果两个对象hashCode()相等,它们并不一定相等。因为在散列表中,hashCode()相等,即两个键值对的哈希值相等。
然而哈希值相等,并不一定能得出键值对相等,此时就出现所谓的哈希冲突场景。也就是Set 存储的是不重复的对象
(hashSet底层是hashMap)
所以说在散列表中 如果重写了 equals() 而未重写 hashcode() 方法,可能就会出现两个没有关系的对象 equals 相同
(因为equal都是根据对象的特征进行重写的),但 hashcode 不相同的情况, 因为在散列表数据结构中要保持key值的唯一,
不然会进行覆盖,通过equals来比较两个key是否相同,也能达到要求,只不过就要和map中的key一个一个的用equals比较,
如果map中有很多元素了,那么效率可能会很低,hashCode方法是根据对象的内存地址经过哈希算法(数据压缩技术,尽量分散
减少哈希冲突)得来的 使用hashCode的一个目的是“分组”,同一个链表上的key的 hashcode是一样的,如果不重写hashcode,
那么两个相同内容的对象,就会放在不同的链表上,那么就会存在两个相同的key。所以就要重写hashcode,
保证有相同内容的对象有相同的hashcode。而且hashcode的结果跟对象的属性有关。如果属性不参与hashcode的计算,
那么这个hash算法就无意义。
如果自定义对象做为 Map 的键,那么必须重写 hashCode 和 equals
这个就是开发规范和Object作者建议的原因