我们如何决定集合的hashCode()方法的最佳实现(假设equals方法已被正确重写)?
当前回答
这里有一个非常严重的bug。
Zam obj1 = new Zam("foo", "bar", "baz");
Zam obj2 = new Zam("fo", "obar", "baz");
同样的hashcode
你可能想要
public int hashCode() {
return (getFoo().hashCode() + getBar().hashCode()).toString().hashCode();
(现在你能在Java中直接从int获取hashCode吗?我认为它做了一些自动铸造。如果是这种情况,跳过toString,它很难看。)
其他回答
当组合哈希值时,我通常使用boost c++库中使用的组合方法,即:
seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
这在确保平均分配方面做得相当好。有关这个公式如何工作的一些讨论,请参阅StackOverflow的帖子:boost::hash_combine中的魔术数字
在http://burtleburtle.net/bob/hash/doobs.html上有关于不同哈希函数的很好的讨论
如果我正确理解你的问题,你有一个自定义的集合类(即一个从集合接口扩展的新类),你想实现hashCode()方法。
如果您的集合类扩展了AbstractList,那么您就不必担心它,因为已经有equals()和hashCode()的实现,它通过遍历所有对象并将它们的hashCodes()相加来工作。
public int hashCode() {
int hashCode = 1;
Iterator i = iterator();
while (i.hasNext()) {
Object obj = i.next();
hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());
}
return hashCode;
}
现在,如果你想要的是计算特定类哈希码的最佳方法,我通常使用^(按位排他或)操作符来处理我在equals方法中使用的所有字段:
public int hashCode(){
return intMember ^ (stringField != null ? stringField.hashCode() : 0);
}
最好使用Eclipse提供的功能,它做得非常好,您可以把精力和精力放在开发业务逻辑上。
首先确保equals被正确实现。摘自一篇IBM DeveloperWorks文章:
对称性:对于两个参考,a和b,当且仅当b等于(a)时,a等于(b) 自反性:对于所有非空引用,a.equals(a) 及物性:如果a等于(b) b等于(c),那么a等于(c)
然后确保它们与hashCode的关系尊重联系人(来自同一篇文章):
与hashCode()的一致性:两个相等的对象必须具有相同的hashCode()值
最后,一个好的哈希函数应该努力接近理想的哈希函数。
关于8.blogspot.com,你说过
如果equals()对于两个对象返回true,那么hashCode()应该返回相同的值。如果equals()返回false,那么hashCode()应该返回不同的值
我不同意你的看法。如果两个对象具有相同的hashcode,并不意味着它们是相等的。
如果A等于B,那么A.hashcode必须等于B.hascode
but
如果A.hashcode等于B.hascode,这并不意味着A必须等于B
推荐文章
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作
- 在Java流是peek真的只是调试?
- Recyclerview不调用onCreateViewHolder
- 将JSON字符串转换为HashMap