栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

将对象的哈希码定义为所有类变量哈希码的总和,乘积或其他乘积是不正确的吗?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

将对象的哈希码定义为所有类变量哈希码的总和,乘积或其他乘积是不正确的吗?

这取决于您所说的“正确”。假设您正在使用

hashCode()
所有相关的
equals()
-defining字段,那么是的,它是“正确的”。但是,此类公式可能不会具有良好的分布,因此可能导致比其他情况更多的冲突,这将对性能产生不利影响。

这是来自 有效Java 2nd Edition条款 9 的引文:覆盖

hashCode
时始终覆盖
equals

尽管此项目中的配方产生了相当不错的哈希函数,但它没有产生最新的哈希函数,Java平台库也没有提供1.6版以上的哈希函数。编写这样的哈希函数是一个研究主题,数学家和计算机科学家最好去做。[…尽管如此]此项中描述的技术对于大多数应用来说应该是足够的。

评估拟议的哈希函数的性能可能不需要很多数学能力,但是为什么还要打扰呢?为什么不只是遵循经实践证明已足够的方法呢?

乔什·布洛赫(Josh Bloch)的食谱

  • 将一个恒定的非零值(例如17)存储在
    int
    名为的变量中
    result
  • 计算每个字段的
    int
    哈希码
    c
    • 如果该字段为
      boolean
      ,则计算
      (f ? 1 : 0)
    • 如果该字段为
      byte, char, short, int
      ,则计算
      (int) f
    • 如果该字段为
      long
      ,则计算
      (int) (f ^ (f >>> 32))
    • 如果该字段为
      float
      ,则计算
      Float.floatToIntBits(f)
    • 如果该字段是
      double
      ,计算
      Double.doubleToLongBits(f)
      ,则
      long
      按照上述方法对结果进行哈希处理。
    • 如果字段是对象引用,并且此类的
      equals
      方法通过递归调用
      equals
      ,递归调用字段来比较
      hashCode
      字段。如果该字段的值为
      null
      ,则返回0。
    • 如果该字段是数组,则将其视为每个元素都是一个单独的字段。如果数组字段中的每个元素都很重要,则可以使用
      Arrays.hashCode
      版本1.5中添加的方法之一。
  • 将哈希码
    c
    合并
    result
    如下:
    result = 31 * result + c;

现在,该配方当然很复杂,但是幸运的是,由于

java.util.Arrays.hashCode(Object[])
(并
com.google.common.base.Objects
提供了一个方便的vararg变体),您不必每次都重新实现它。

@Override public int hashCode() {    return Arrays.hashCode(new Object[] {myInt,    //auto-boxedmyDouble, //auto-boxedmyRandomClass,    });}

也可以看看

  • Object.hashCode()


要求,如果两个对象根据是不相等的

equals(java.lang.Object)
方法,然后调用
hashCode
在每个两个对象的方法必须产生不同的整数结果。
但是, 程序员应该意识到,为不相等的对象生成不同的整数结果可能会提高哈希表的性能。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/515358.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号