equal() class 实例仅通过其唯一的 instanceID 是不好的做法吗?

Is it bad practice to equal() class instances by just their unique instanceID?

我有一个 class,它在实例化时为其对象创建一个唯一 ID,如下所示:

public class Foo {

    private final static AtomicInteger UNIQUE_ID = new AtomicInteger(0);
    private final int id;
    private final String name;         
    private final int hashcode;
    public Foo(String name) {
         id = UNIQUE_ID.GetAndIncrement();
         this.name = name;
         int result = 17;
         int result = 31 * result + id;
         int result = 31 * result + name.hashCode();
         hashcode = result;
    }
    public int getInstanceID() { return id; }

现在我想这样实现 hashCode 和 equals:

    public boolean equals(Object obj) {

        if (obj == this)
            return true;
        if (!(obj instanceof Foo))
            return false;

        Foo other = (Foo) obj;
        return other.getInstanceID == getInstanceID();
    }

    public int hashCode() { return hashcode; }
}

如果我只比较对象的 ID 而忽略可能不同于一个 Foo istance 的任何其他字段,这是否被认为是不好的做法?此外,我是否仍应考虑哈希码函数中的每个字段,还是只使用 id?

嗯。契约是这样的——如果两个对象相等,则它们必须具有相同的hashCode。您还没有覆盖 hashCode(),因此您可以拥有 2 个具有不同哈希码的相等对象,这是错误的。覆盖 hashcode() 以遵守合同,那么它可能 就好了

最佳实践是以这样一种方式实现 hashCode 函数,以便它均匀分布集合(哈希表)中的对象。产生相同 hashCode 的对象进入同一个桶。 hashCode函数的作用是识别bucket。

如果你有一个不好的函数,它 returns 所有的值都相同,那么想象一下所有对象都存储在一个桶中。这使得集合的工作变得困难,因为它必须遍历每个对象并且 运行 对它们使用 equals 方法,直到找到合适的对象(如果可用)。

当你有一个好的 hashCode 函数时,不同的对象由不同的桶标识。因此给定桶中的对象更少,这意味着需要更少的搜索。

最好使用对象的属性来唯一标识它。