dev*_*ium 9 .net c# java hashcode
假设我有以下课程:
class ABC {
private int myInt = 1;
private double myDouble = 2;
private String myString = "123";
private SomeRandomClass1 myRandomClass1 = new ...
private SomeRandomClass2 myRandomClass2 = new ...
//pseudo code
public int myHashCode() {
return 37 *
myInt.hashcode() *
myDouble.hashCode() *
... *
myRandomClass.hashcode()
}
}
Run Code Online (Sandbox Code Playgroud)
这是hashCode的正确实现吗?这不是我通常这样做的方式(我倾向于遵循Effective Java的指导方针),但我总是有诱惑去做类似上面代码的事情.
谢谢
pol*_*nts 13
这取决于你所说的"正确".假设您正在使用hashCode()所有相关的equals()定义字段,那么是的,它是"正确的".然而,这样的公式可能不会有良好的分布,因此可能会导致更多的碰撞,这将对性能产生不利影响.
以下是Effective Java 2nd Edition的引用,第9项:覆盖hashCode时始终覆盖equals
虽然这个项目中的配方产生了相当好的散列函数,但它不会产生最先进的散列函数,Java平台库也不提供1.6版本的散列函数.编写这样的哈希函数是一个研究课题,最好留给数学家和计算机科学家.[...尽管如此,]此项目中描述的技术应该适用于大多数应用程序.
它可能不需要很多数学能力来评估你提出的哈希函数有多好,但为什么还要费心呢?为什么不遵循经过传闻证明在实践中足够的东西呢?
int名为的变量中存储一些常量非零值,比如17 result.int哈希码c:
boolean,则计算(f ? 1 : 0)byte, char, short, int,则计算(int) flong,则计算(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提供了一个方便的变量).
@Override public int hashCode() {
return Arrays.hashCode(new Object[] {
myInt, //auto-boxed
myDouble, //auto-boxed
myRandomClass,
});
}
Run Code Online (Sandbox Code Playgroud)
Object.hashCode()
如果两个对象根据方法不相等则不是必需的,则在两个对象中的每一个上
equals(java.lang.Object)调用hashCode方法必须产生不同的整数结果.但是,程序员应该知道为不等对象生成不同的整数结果可能会提高哈希表的性能.