Java集合获取重复项
JavaDoc将集合定义为: 不包含重复元素的集合。更正式地说,设置 不包含一对元素e1和e2,以使e1等于(e2) 为了验证这一点,我创建了一个非常简单的程序:Java集合获取重复项,java,collections,set,unique,hashset,Java,Collections,Set,Unique,Hashset,JavaDoc将集合定义为: 不包含重复元素的集合。更正式地说,设置 不包含一对元素e1和e2,以使e1等于(e2) 为了验证这一点,我创建了一个非常简单的程序: import java.util.HashSet; public class CheckHashSet { public static void main(String[] args) { HashSet<Employee> set = new HashSet<Employee>();
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;
}
}
}
这意味着new Employee(10).equals(new Employee(10))
返回true,而set.add(new Employee(10));增加(新员工(10人))代码>将对象添加两次
我的代码有什么问题?您的Employee
类没有重写hashCode
——它需要这样做才能使任何基于哈希的集合工作
例如:
@Override
public int hashCode() {
return id;
}
您的Employee
类不会重写hashCode
——它需要这样做才能使任何基于哈希的集合工作
例如:
@Override
public int hashCode() {
return id;
}
你的班级在和上签署了联合合同:
请注意,每当重写equals
方法时,通常需要重写hashCode
方法,以便维护hashCode方法的一般约定,其中规定相等的对象必须具有相等的哈希代码。
在您的情况下,相等的对象不一定具有相等的哈希代码。这就是造成哈希集
混乱的原因,因为拥有相同id的员工
可能会被放在不同的桶中,并因此被视为不平等
要修复,请重写hashCode()
[例如,只需返回this.id
。您的类在和上查看联合契约:
请注意,每当重写equals
方法时,通常需要重写hashCode
方法,以便维护hashCode方法的一般约定,其中规定相等的对象必须具有相等的哈希代码。
在您的情况下,相等的对象不一定具有相等的哈希代码。这就是造成哈希集
混乱的原因,因为拥有相同id的员工
可能会被放在不同的桶中,并因此被视为不平等
要解决此问题,请重写hashCode()
[例如,只需返回this.id
。可能是您的问题返回this.id-o.id
而是检查返回这个。等于(o)
返回true或false。可能是您的问题返回这个.id-o.id
而是选择返回该值。equals(o)
返回true或false。HashSet
基于数据结构,因此您必须重写类Employee
中的equals
和hashCode
方法以使其正常工作
但是,您可以使用另一个不基于哈希表的Set
实现,例如TreeSet
HashSet
基于数据结构,因此必须重写类Employee
中的equals
和hashCode
方法,以使其正常工作
但是,您可以使用另一个不基于哈希表的Set
实现,例如TreeSet
阅读:阅读:你真的在21秒内输入答案并格式化了吗?我放弃:-)这会让事情变得更好。你真的在21秒内输入答案并格式化了吗?我放弃:-)这会让事情好一点。这里面可能有什么问题。我不认为这是问题。这里面可能有什么问题。我不认为这是问题。这就是我一直在寻找的解决方案。JavaDoc提到它是因为Set接口在所有构造函数的约定以及add、equals和hashCode方法的约定上,除了从集合接口继承的约定之外,还添加了其他约定。@PC:不,这根本不是一回事。这是对集合的附加规定——aix引用的javadoc是关于集合中元素的需求。谢谢。这就是我一直在寻找的解决方案。JavaDoc提到它是因为Set接口在所有构造函数的约定以及add、equals和hashCode方法的约定上,除了从集合接口继承的约定之外,还添加了其他约定。@PC:不,这根本不是一回事。这是对集合的附加规定——aix引用的javadoc是关于集合中元素的需求。