为什么哈希集允许添加重复对象?
Why hash set allows adding duplicate object?
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Vector;
public class Test {
public static void main(String[] args) {
Employee e1 = new Employee("abc",10.0);
Employee e3 = new Employee("abc",10.0);
HashSet<Employee> hs = new HashSet<Employee>();
hs.add(e1);
hs.add(e3);
System.out.println("size of hs : "+hs.size());
Object [] aa = hs.toArray();
for(int i=0;i<aa.length;i++){
Object ii = aa[i];
System.out.println("ii "+(i+1)+"="+ii.toString());
}
Iterator it = hs.iterator();
while(it.hasNext()){
Employee e4 = (Employee) it.next();
System.out.println("e4 ="+e4);
System.out.println("111="+it.next());
}
Enumeration e5 = new Vector(hs).elements();
while(e5.hasMoreElements()){
Employee e6 = (Employee) e5.nextElement();
System.out.println("e6 ="+e6);
}
}
}
public class Employee {
private String name;
private Double salary;
public Employee(String name, Double salary){
this.name = name;
this.salary = salary;
}
public Employee(String name){
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getSalary() {
return salary;
}
public void setSalary(Double salary) {
this.salary = salary;
}
@Override
public String toString() {
return "Employee [name=" + name + ", salary=" + salary + "]";
}
public void getNameSal() throws NullPointerException{
System.out.println(this.name +""+this.salary);
}
}
查看上面的代码,我创建了一个哈希集,它接受 Employee
class 的对象。
我创建了两个具有相同值的 Employee
class 对象并添加到哈希集中。
但是当我打印散列集的大小时它显示 2。
而且,当通过将其转换为数组 Iterator
和 Enumerator
以三种方式进行迭代时,它会显示两个重复的值。
但是当我尝试使用 it.next()
打印时,它只打印单个值。
为什么会这样?
Output:
size of hs : 2
ii 1=Employee [name=abc, salary=10.0]
ii 2=Employee [name=abc, salary=10.0]
e4 =Employee [name=abc, salary=10.0]
111=Employee [name=abc, salary=10.0]
e6 =Employee [name=abc, salary=10.0]
e6 =Employee [name=abc, salary=10.0]
如果您没有为您的 Employee class 实现 equals() 和 hashCode(),HashSet 使用默认的 equals 实现,即一个对象只等于它自己。因此,您的两个 Employee 对象不相等,因此第二个对象不会覆盖第一个。
因此,解决方案是在您的 Employee class 上实施 equals() 和 hashCode() 并检查您定义的两个 Employees 相等的所有字段是否相等。
你只看到一个员工被打印出来,因为你的代码中有一个错误:你在第一个 while 循环的每次迭代中调用 next() 两次。
HashSet
正在使用幕后对象的 hashCode
和 equals
方法。
由于您没有为您的 Employee
class 覆盖这些方法,因此 HashSet
只能看到两个 Employees 在共享同一个实例时是相等的。
要解决您的问题,您需要覆盖 Employee
class.
中的 hashCode
和 equals
方法
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Vector;
public class Test {
public static void main(String[] args) {
Employee e1 = new Employee("abc",10.0);
Employee e3 = new Employee("abc",10.0);
HashSet<Employee> hs = new HashSet<Employee>();
hs.add(e1);
hs.add(e3);
System.out.println("size of hs : "+hs.size());
Object [] aa = hs.toArray();
for(int i=0;i<aa.length;i++){
Object ii = aa[i];
System.out.println("ii "+(i+1)+"="+ii.toString());
}
Iterator it = hs.iterator();
while(it.hasNext()){
Employee e4 = (Employee) it.next();
System.out.println("e4 ="+e4);
System.out.println("111="+it.next());
}
Enumeration e5 = new Vector(hs).elements();
while(e5.hasMoreElements()){
Employee e6 = (Employee) e5.nextElement();
System.out.println("e6 ="+e6);
}
}
}
public class Employee {
private String name;
private Double salary;
public Employee(String name, Double salary){
this.name = name;
this.salary = salary;
}
public Employee(String name){
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getSalary() {
return salary;
}
public void setSalary(Double salary) {
this.salary = salary;
}
@Override
public String toString() {
return "Employee [name=" + name + ", salary=" + salary + "]";
}
public void getNameSal() throws NullPointerException{
System.out.println(this.name +""+this.salary);
}
}
查看上面的代码,我创建了一个哈希集,它接受 Employee
class 的对象。
我创建了两个具有相同值的 Employee
class 对象并添加到哈希集中。
但是当我打印散列集的大小时它显示 2。
而且,当通过将其转换为数组 Iterator
和 Enumerator
以三种方式进行迭代时,它会显示两个重复的值。
但是当我尝试使用 it.next()
打印时,它只打印单个值。
为什么会这样?
Output:
size of hs : 2
ii 1=Employee [name=abc, salary=10.0]
ii 2=Employee [name=abc, salary=10.0]
e4 =Employee [name=abc, salary=10.0]
111=Employee [name=abc, salary=10.0]
e6 =Employee [name=abc, salary=10.0]
e6 =Employee [name=abc, salary=10.0]
如果您没有为您的 Employee class 实现 equals() 和 hashCode(),HashSet 使用默认的 equals 实现,即一个对象只等于它自己。因此,您的两个 Employee 对象不相等,因此第二个对象不会覆盖第一个。 因此,解决方案是在您的 Employee class 上实施 equals() 和 hashCode() 并检查您定义的两个 Employees 相等的所有字段是否相等。
你只看到一个员工被打印出来,因为你的代码中有一个错误:你在第一个 while 循环的每次迭代中调用 next() 两次。
HashSet
正在使用幕后对象的 hashCode
和 equals
方法。
由于您没有为您的 Employee
class 覆盖这些方法,因此 HashSet
只能看到两个 Employees 在共享同一个实例时是相等的。
要解决您的问题,您需要覆盖 Employee
class.
hashCode
和 equals
方法