繁体   English   中英

在java中编写哈希函数的最佳实践是什么?

[英]What is a best practice of writing hash function in java?

我想知道在java中编写#hashCode()方法的最佳实践是什么。 很好的描述可以在这里找到。 这样好吗?

下面是有效的Java第二版报价,第9项:“总是覆盖hashCode当您覆盖equals ”:

虽然这个项目中的配方产生了相当好的散列函数,但它不会产生最先进的散列函数,Java平台库也不提供1.6版本的散列函数。 编写这样的哈希函数是一个研究课题,最好留给数学家和计算机科学家。 [...尽管如此,]此项目中描述的技术应该适用于大多数应用程序。

Josh Bloch的食谱

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

现在,当然这个配方相当复杂,但幸运的是,你不必每次都重新实现它,这要归功于java.util.Arrays.hashCode(Object[])

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

从Java 7开始, java.util.Objects.hash(Object...)有一个方便的varargs变体。

Effective Java ”一书中描述了hashCode()实现的一个很好的参考。 在了解了生成良好哈希函数背后的理论之后,您可以从Apache commons lang中检查HashCodeBuilder ,它实现了本书中描述的内容。 来自文档:

这个类可以为任何类构建一个好的hashCode方法。 它遵循Joshua Bloch撰写的Effective Java一书中规定的规则。 编写好的hashCode方法实际上非常困难。 本课程旨在简化流程。

正如@leonbloy所说,好好理解它。 然而,即便如此,一个“最佳”的做法是简单地让IDE为您编写功能。 在某些情况下它不会是最佳的 - 在一些非常罕见的情况下它甚至都不会好 - 但在大多数情况下,它很容易,可重复,没有错误,并且像它需要一样好(作为哈希码)成为。 当然,阅读文档并理解它 - 但不要不必要地使它复杂化。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM