刘浩田

博客园 首页 新随笔 联系 订阅 管理

  阿里巴巴开发规范

只要重写 equals,就必须重写 hashCode

因为 Set 存储的是不重复的对象,依据 hashCode 和 equals 进行判断,所以 Set 存储的对象必须重写这两个方法

如果自定义对象做为 Map 的键,那么必须重写 hashCode 和 equals

  Object作者建议

相同的对象必然是相同的哈希值,不同的哈希值是不同的对象

 

在开发规范和Object作者建议 中都是只要重写 equals, 就必须重写 hashCode 为什么?

要明白重写equals的原因要先明白equals是什么,与之关联的 ==,hashCode又是什么?

== :是对于基本数据类型的值比较

equals :定义在JDK的Object.java中 这就意味着Java中的任何类都包含有equals()函数

equals默认下情况比较两个对象的地址是否相同   如果对象重写了equals()方法,比较两个对象的内容是否相等

但很多类都重写了equals方法,像String,基本数据的包装类等把他变成了值比较 所以一般情况下equals比较的是值是否相等

hashCode :hashCode() 定义也在JDK的Object.java中

hashCode() 的作用是获取哈希码,它实际上是返回一个int整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。

 

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作者建议的原因

 

posted on 2021-12-05 16:08  刘浩田  阅读(1284)  评论(1编辑  收藏  举报