集合的hashCode方法的最佳实现

本文翻译自: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... 会打败整个目标...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值