JavaDoc将set定义为:
不包含重复元素的集合。更正式的,集合 不包含元素对e1和e2,使得e1.equals(e2)
为了验证相同,我创建了一个非常简单的程序:
import java.util.HashSet;
public class CheckHashSet {
public static void main(String[] args) {
HashSet<Employee> set = new HashSet<Employee>();
set.add(new Employee(10));
set.add(new Employee(10));
System.out.println(set.size());
System.out.println(new Employee(10).equals(new Employee(10)));
}
private static class Employee implements Comparable<Employee> {
private final int id;
public Employee(int id) {
this.id = id;
}
@Override
public int compareTo(Employee o) {
return this.id - o.id;
}
@Override
public boolean equals(Object obj) {
if(obj instanceof Employee) {
return compareTo((Employee)obj)==0;
}
return false;
}
}
}
程序的输出是
2
true
这意味着new Employee(10).equals(new Employee(10))
返回true,而set.add(new Employee(10)); set.add(new Employee(10));
将对象添加两次。
我的代码出了什么问题?
答案 0 :(得分:7)
您的Employee
类不会覆盖hashCode
- 它需要这样做才能使任何基于散列的集合都能正常工作。
例如:
@Override
public int hashCode() {
return id;
}
答案 1 :(得分:4)
您的班级通过equals()
和hashCode()
请注意,通常需要在覆盖
hashCode
方法时覆盖equals
方法,以便维护hashCode方法的常规协定,指出相等的对象必须具有相等的哈希码。
在您的情况下,相等的对象不一定具有相同的哈希码。这使HashSet
感到困惑,因为具有相同Employees
的{{1}}最终会出现在不同的存储桶中,因此会被视为不相等。
要修复,请覆盖id
[例如,只需返回hashCode()
]。
答案 2 :(得分:1)
HashSet
基于Hash Table数据结构,因此您必须覆盖类equals
中的hashCode
和Employee
方法才能使其正常运行。< / p>
但是,您可以使用不基于哈希表的其他Set
实现,例如TreeSet
。
答案 3 :(得分:0)
也许这是您的问题return this.id - o.id;
,而不是检查return this.equals(o)
返回true或false。