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
这是一个来自模拟考试的问题,我正在为第8章做准备,我对选项C有疑问。它说"正确地工作",所以并不意味着需要覆盖哈希码?虽然不会覆盖hashcode()
会起作用,但我会关注正确这个词!
答案 0 :(得分:4)
未正确实现等于,它需要一个Object,而不是Person作为参数。
由于private修饰符,编译不会失败。私人访问成员可以从周围的整个班级访问。
对于基于散列的数据结构,这将无法正常工作,因为当A.equals(B)或B.equals(A)时,两个实例A和B的hashCode()必须相等。目前,hashCode的默认实现基于实例,而不是name
的相等。
是的,equals(Object)
方法将用于确定java.util.Set
中的条目是否确实相等;但是,如果它是基于散列的Set
,那么hashCode()可以用作确定相等性的捷径。如果hashSet()
未正确实施,则Set
可能决定之后不再调用equals(Object)
,因为hashCode()
表示这两个对象不能相等。
请注意,hashCode()
的正确实现可以明确确定对象是否不等于,但无法明确确定对象是否等于;仅为equals(Object)
保留。 HashCode()
通常调用非常快,因此通常在实际调用equals(Object)
之前用于丢弃所需的相等性检查以确定真正的相等性。
请注意,此类缺少equals(Object)
方法(但它具有类似命名的equals(Person)
方法,由于方法签名错误,不会在等式检查中使用)。因此,如果意图是每个名称在集合中有一个条目,则此类将无法在Set
中正常工作。但是,equals(Object)
的默认实现是有效的,hashCode()
的默认实现也是有效的,因此它可以在Set
内正常工作;但是,只有当意图不在Set
内两次存储相同的实例时。
答案 1 :(得分:2)
是的,答案C是正确的。
您应该专注于正确这个词。为了使这个类能够与基于哈希的结构一起正常工作,它必须按照equals-hashcode契约的方式以与`equals()`的实现一致的方式实现`hashCode()`。
来自hashcode()的javadoc:
hashCode的一般合约是:
- 每当在同一个对象上多次调用它时 在执行Java应用程序期间,hashCode方法必须 如果没有使用任何信息,则始终返回相同的整数 等于对象的比较被修改。这个整数不需要 从应用程序的执行到另一个应用程序保持一致 执行相同的应用程序。
- 如果两个对象相等 根据equals(Object)方法,然后调用hashCode 对两个对象中的每一个的方法必须产生相同的整数 结果。
- 如果两个对象不相等,则不需要 根据equals(java.lang.Object)方法,然后调用 每个两个对象上的hashCode方法必须产生不同的 整数结果。但是,程序员应该意识到这一点 为不相等的对象产生不同的整数结果可以改善 哈希表的性能。
答案 2 :(得分: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)