我看了一下IntelliJ默认的hashCode()
实现,想知道他们为什么要这样实现。由于我对哈希概念很陌生,找到了一些矛盾的说法,需要澄清:
public int hashCode(){
// creationDate is of type Date
int result = this.creationDate != null ? this.creationDate.hashCode() : 0;
// id is of type Long (wrapper class)
result = 31 * result + (this.id != null ? this.id.hashCode() : 0);
// code is of type String
result = 31 * result + (this.code != null ? this.code.hashCode() : 0);
// revision is of type int
result = 31 * result + this.revision;
return result;
}
在我看来,关于这个主题最好的资源似乎是这篇Java World文章,因为我发现他们的论点最具有说服力。所以我想知道:
- 上述资源中提到的其中一个论点是,乘法是较慢的操作之一。那么,当我调用引用类型的
hashCode()
方法时,跳过与质数的乘法运算是否更好呢?因为大多数情况下,这已经包括了这样的乘法运算。 - Java World指出,位异或
^
也可以改善计算,但没有提到原因:(相比普通加法,确切地说可能有什么优势呢? - 如果返回的类字段为
null
,返回不同的值是否更好?这将使结果更易区分,对于使用非零值是否有巨大的不利影响?
老实说,他们的示例代码更吸引人:
public boolean hashCode() {
return
(name == null ? 17 : name.hashCode()) ^
(birth == null ? 31 : name.hashCode());
}
但我不确定这是否客观真实。我也有点怀疑IntelliJ,因为它们默认的equals(Object)
代码是通过instanceof
进行比较,而不是直接比较实例类。我同意这篇Java world文章的观点,这似乎无法正确履行合同。