import java.util.*;
public class Measurement {
int count;
int accumulated;
public Measurement() {}
public void record(int v) {
count++;
accumulated += v;
}
public int average() {
return accumulated/count;
}
public boolean equals(Object other) {
if (this == other)
return true;
if (!(other instanceof Measurement))
return false;
Measurement o = (Measurement) other;
if (count != 0 && o.count != 0)
return average() == o.average();
return count == o.count;
}
public int hashCode() {
(1) INSERT CODE HERE
}
}
在(1)处插入哪个代码,将在以下程序中提供hashCode()方法的正确实现?选择两个正确的答案。
(a) return 31337;
(b) return accumulated / count;
(c) return (count << 16) ^ accumulated;
(d) return ~accumulated;
(e) return count == 0 ? 0 : average();
正确的答案是(a)和(e)。 (b)由于计数不正确,如果为0,它将生成算术异常,但我不知道(c)和(d)的平均值。为什么它们是假的?
答案 0 :(得分:2)
这里是Object.hashCode
中的general contract。问题基本上是在问您哪些选择符合总合同。
在Java应用程序执行期间,只要在同一对象上多次调用它,hashCode方法就必须一致 返回相同的整数,前提是不包含等于的信息 对象上的比较被修改。该整数不必保留 从应用程序的一次执行到另一次执行的一致性 相同的应用程序。
如果根据equals(Object)方法两个对象相等,则必须在两个对象中的每个对象上调用hashCode方法 产生相同的整数结果。
如果根据equals(java.lang.Object)方法,如果两个对象不相等,则不需要调用hashCode方法 两个对象中的每一个必须产生不同的整数结果。 但是,程序员应该意识到, 不相等对象的整数结果可能会提高 哈希表。
您对为什么B不正确的理解是正确的。 C和D不正确,因为它们不满足第二点。也就是说,它们不适用于equals
。
如您所见,如果equals
均不为0,则count
方法将比较平均值,否则将比较count
。
选项C同时考虑了计数和累加,因此(累加:6,计数:2)和(累加:3,计数:1)将具有不相等的哈希码,但被{{1 }}。
选项D仅考虑累加,因此(累加:6,计数:2)和(累加:3,计数:1)将具有不相等的哈希码,但被equals
视为相等
选项A很奇怪。它返回一个常量整数。这意味着所有对象将具有相同的哈希码。尽管一般合同不需要为不同的对象使用不同的哈希码(请参阅第3点),但这很少有用。