第11条 覆盖equals
时总要覆盖hashCode
这一条在我们使用Set
和Map
的时候尤为重要
hashcode
的要求
对于hashCode
方法,主要要满足3点要求:
- 程序执行期间,只要对象的
equals
方法的比较操作所用到的信息没有被修改,那么多次调用hashCode
方法都必须始终如一地返回同一个整数 - 如果两个对象根据
equals
比较相等,那么hashCode
结果应该相同 - 如果两个对象使用
equals
比较必相等,则hashcode
不一定要得到不一样的结果。但是如果结果不同可以调高散列表的性能
重写hashcode
的方法
- 如果是基本数据类型,则可以调用对用类型的
Type.hashCode(f)
方法 - 如果是一个对象引用,则应该调用该对象的
hashcode
方法 - 如果是一个数组,则需要把每一个元素单独处理。如果有些元素重要,有些不重要,可以只挑出来重要的元素
- 最后把所有元素的hash结果按照公式加总:
resuot = 31 * result + c
hashcode
工具方法
-
com.google.common.hash.Hashing
,这个是google的Guava提供的方法,它尽量保证了不会出现哈希冲突 -
Objects.hashcode
,它是JDK官方 提供的hash计算方法。缺点是因为它要创建数组,在速度上会慢一些
其它
- 如果计算hashcode性能开销非常大,可以将一个对象的hashcode缓存在对象内部
- 不要通过避免计算对象的关键字段的哈希值来提高hash的计算性能,因为这样会导致hash计算的结果意义不大
个人感觉,我们在比较对象的时候,应当尽量保证不同对象的hash值不同。因为hash的性能应该比equals要好。我们重写hashcode和equals的主要目的是为了给Collection,尤其是Map和Set使用。这里面对于数据结构来说会有比较多的比较计算。如果可以用性能更好的hashcode就能区分对象,会对性能的提升有比较大的帮助
网友评论