本文翻译自:Best implementation for hashCode method for a collection
我们如何确定最佳的hashCode()
方法实现集合(假设equals方法已被正确重写)?
#1楼
参考:https://stackoom.com/question/TWp/集合的hashCode方法的最佳实现
#2楼
For a simple class it is often easiest to implement hashCode() based on the class fields which are checked by the equals() implementation. 对于一个简单的类,通常最容易基于由equals()实现检查的类字段来实现hashCode()。
public class Zam {
private String foo;
private String bar;
private String somethingElse;
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Zam otherObj = (Zam)obj;
if ((getFoo() == null && otherObj.getFoo() == null) || (getFoo() != null && getFoo().equals(otherObj.getFoo()))) {
if ((getBar() == null && otherObj. getBar() == null) || (getBar() != null && getBar().equals(otherObj. getBar()))) {
return true;
}
}
return false;
}
public int hashCode() {
return (getFoo() + getBar()).hashCode();
}
public String getFoo() {
return foo;
}
public String getBar() {
return bar;
}
}
The most important thing is to keep hashCode() and equals() consistent: if equals() returns true for two objects, then hashCode() should return the same value. 最重要的是使hashCode()和equals()保持一致:如果equals()对两个对象返回true,则hashCode()应该返回相同的值。 If equals() returns false, then hashCode() should return different values. 如果equals()返回false,则hashCode()应该返回不同的值。
#3楼
@about8 : there is a pretty serious bug there. @ about8:那里有一个非常严重的错误。
Zam obj1 = new Zam("foo", "bar", "baz");
Zam obj2 = new Zam("fo", "obar", "baz");
same hashcode 相同的哈希码
you probably want something like 你可能想要像
public int hashCode() {
return (getFoo().hashCode() + getBar().hashCode()).toString().hashCode();
(can you get hashCode directly from int in Java these days? I think it does some autocasting.. if that's the case, skip the toString, it's ugly.) (这些天,您可以直接从Java中的int获取hashCode吗?我认为它会进行一些自动广播。如果是这种情况,请跳过toString,这很丑陋。)
#4楼
First make sure that equals is implemented correctly. 首先,请确保正确实施了equals。 From an IBM DeveloperWorks article : 从IBM DeveloperWorks文章中 :
- Symmetry: For two references, a and b, a.equals(b) if and only if b.equals(a) 对称性:对于两个引用a和b,当且仅当b.equals(a)时,a.equals(b)
- Reflexivity: For all non-null references, a.equals(a) 自反性:对于所有非空引用,a.equals(a)
- Transitivity: If a.equals(b) and b.equals(c), then a.equals(c) 传递性:如果a.equals(b)和b.equals(c),则a.equals(c)
Then make sure that their relation with hashCode respects the contact (from the same article): 然后确保他们与hashCode的关系尊重该联系人(来自同一篇文章):
- Consistency with hashCode(): Two equal objects must have the same hashCode() value 与hashCode()的一致性:两个相等的对象必须具有相同的hashCode()值
Finally a good hash function should strive to approach the ideal hash function . 最后,一个好的哈希函数应该努力接近理想的哈希函数 。
#5楼
Just a quick note for completing other more detailed answer (in term of code): 简要说明一下完成其他更详细的答案(根据代码):
If I consider the question how-do-i-create-a-hash-table-in-java and especially the jGuru FAQ entry , I believe some other criteria upon which a hash code could be judged are: 如果我考虑如何在Java中创建哈希表(尤其是jGuru FAQ条目)的问题 ,我认为可以判断哈希码的其他一些标准是:
- synchronization (does the algo support concurrent access or not) ? 同步(算法是否支持并发访问)?
- fail safe iteration (does the algo detect a collection which changes during iteration) 故障安全迭代(算法是否检测到在迭代过程中发生更改的集合)
- null value (does the hash code support null value in the collection) 空值(哈希码是否支持集合中的空值)
#6楼
As you specifically asked for collections, I'd like to add an aspect that the other answers haven't mentioned yet: A HashMap doesn't expect their keys to change their hashcode once they are added to the collection. 正如您特别要求的集合一样,我想添加一个其他答案还没有提到的方面:HashMap不会期望将其键添加到集合后更改其哈希码。 Would defeat the whole purpose... 会打败整个目标...