2
public class Person {
    private String name;
    public Person(String name) { this.name = name; }
    public boolean equals(Person p) {
        return p.name.equals(this.name);
    }
}

    Which statement is true?
    A. The equals method does NOT properly override the Object.equals method.
    B. Compilation fails because the private attribute p.name cannot be accessed in line 5.
    C. To work correctly with hash-based data structures, this class must also implement the
    hashCode method.
    D. When adding Person objects to a java.util.Set collection, the equals method in line 4 will
    prevent duplicates.
    Answer: A

这是一个模拟考试的问题,我正在准备 ocjp 6,我对选项 C 有疑问。它说“正常工作”,所以这是否意味着需要覆盖哈希码?虽然不覆盖hashcode()会起作用,但我专注于“正确”这个

4

3 回答 3

4

Equals 没有正确实现,它需要一个对象,而不是一个人作为参数。

由于 private 修饰符,编译不会失败。私有访问成员可以从整个周围的类中访问。

这不适用于基于散列的数据结构,因为当 A.equals(B) 或 B.equals(A) 时,两个实例 A 和 B 的 hashCode() 必须相等。目前 hashCode 的默认实现是基于实例,而不是name.

是的,该equals(Object)方法将用于确定 a 中的条目是否确实相等java.util.Set;但是,如果它是基于哈希的,Set则 hashCode() 可以用作确定相等性的捷径。如果hashSet()实现不正确,则Set可能决定equals(Object)以后不调用,因为hashCode()s 表示两个对象不能相等。

请注意,正确的实现hashCode()可以明确地确定对象是否不等于,但不能明确地确定对象是否等于;仅保留给equals(Object). HashCode()通常调用速度非常快,因此它通常用于在实际调用之前丢弃所需的相等性检查equals(Object)以确定真正的相等性。

请注意,这个类缺少一个equals(Object)方法(但它有一个类似名称的equals(Person)方法,由于方法签名错误,不会在相等性检查中使用)。Set因此,如果意图是每个名称在集合中有一个条目,则此类将无法正常工作。但是,默认实现equals(Object)是有效的,因为它的默认实现hashCode()是为匹配而定制的,所以它可以在Set;中正常工作。但是,仅当意图是不在Set.

于 2013-09-04T14:15:18.763 回答
2

是的,答案 C 是正确的。

你把注意力集中在正确的词上是对。为了让这个类正确地使用基于散列的结构,它必须以与其实现 `equals()` 一致的方式实现`hashCode()`,根据 equals-hashcode 协定。

来自 hashcode() 的 javadoc:

hashCode 的一般合约是:

  • 每当在 Java 应用程序执行期间对同一个对象多次调用它时,hashCode 方法必须始终返回相同的整数,前提是没有修改对象上的 equals 比较中使用的信息。该整数不需要从应用程序的一次执行到同一应用程序的另一次执行保持一致。
  • 如果两个对象根据 equals(Object) 方法相等,则对两个对象中的每一个调用 hashCode 方法必须产生相同的整数结果。
  • 如果根据 equals(java.lang.Object) 方法,如果两个对象不相等,则不需要对两个对象中的每一个调用 hashCode 方法都必须产生不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同的整数结果可能会提高哈希表的性能。
于 2013-09-04T14:14:42.383 回答
1

答案 C 正确!您还必须在 qay 中实现 hashCode 方法,即两个相等的人也具有相同的哈希码。

如果不这样做,您可以将一个人放入基于哈希的数据结构中,但在另一个实例中找不到它(即等于第一个实例)。

例子:

Person p1 = new Person("me");
Person p2 = new Person("me");
System.out.println(p1.equals(p2)); // prints true
Set<Person> persons = new HashSet<>();
persons.add(p1);
System.out.println(persons.contains(p2)); // prints false (which should be wrong)
于 2013-09-04T14:19:57.817 回答