我找到了OCPJP的以下问题:
class Student{
public Student(int r) {
rollNo = r;
}
int rollNo;
public int hashCode(){
return rollNo;
}
}
class Test {
public static void main(String[] args){
HashSet<Student> students = new HashSet<>();
students.add(new Student(5));
Student s10 = new Student(10);
students.add(s10);
System.out.println(students.contains(new Student(10)));
System.out.println(students.contains(s10));
}
} 输出是: 假 真
你甚至可以从一套中删除s10。 如果没有覆盖等于,这怎么工作?
答案 0 :(得分:1)
如果你不覆盖equals
,那么它基本上会检查被比较的两个对象在内存中是否相同。由于您实际上是针对自身检查s10
,因此标准equals
评估为true
,因为它是同一个对象。
这是contains
that explains this上的文档:“如果此集合包含指定的元素,则返回true。更正式地,当且仅当此集合包含元素e (o==null ? e==null : o.equals(e))
时才返回true。”
并且,对于Object.equals
:“类Object的equals方法实现了对象上最具辨别力的可能等价关系;也就是说,对于任何非空引用值x和y,此方法仅返回true如果x和y引用同一个对象(x == y的值为true)。“
答案 1 :(得分:1)
默认的equals
方法相当于==
,因此它会为s10.equals(s10)
返回true,默认的hash
方法将始终返回{{1}的相同值}}
因此,默认情况下,只要您添加,检查和删除相同的物理对象,s10
就会起作用。
这通常不常用,因为你经常会丢失对原始键的引用并且将构造一个新键(但是如果你使用常量键,只要你在同一个类加载器中它就可以工作)。