为什么hashCode()函数会产生错误

时间:2019-05-13 16:08:15

标签: java

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)的平均值。为什么它们是假的?

1 个答案:

答案 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点),但这很少有用。