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 函数时,不同的对象由不同的桶标识。因此给定桶中的对象更少,这意味着需要更少的搜索。
最好使用对象的属性来唯一标识它。
我有一个 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 函数时,不同的对象由不同的桶标识。因此给定桶中的对象更少,这意味着需要更少的搜索。
最好使用对象的属性来唯一标识它。