为什么哈希集允许添加重复对象?

时间:2015-10-24 15:50:11

标签: java hashset

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类对象的哈希集。 我创建了两个具有相同值的Employee类对象,并添加到哈希集中。 但是当我打印哈希集的大小时,它显示2。 而且,当通过三种方式迭代将其转换为数组IteratorEnumerator时,它会显示两个重复的值。 但是当我尝试使用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]

2 个答案:

答案 0 :(得分:2)

如果没有为Employee类实现equals()和hashCode(),HashSet使用默认的equals实现,即一个对象只等于它自己。因此,您的两个Employee对象不相等,因此第二个对象不会覆盖第一个。 因此,解决方案是在Employee类上实现equals()和hashCode(),并检查所有字段是否相等,这是两个Employees相等的定义的一部分。

您只会看到一位员工打印出来,因为您的代码中存在错误:您在第一次while循环中每次迭代时调用next()两次。

答案 1 :(得分:1)

HashSet正在使用幕后对象的hashCodeequals方法。

由于您没有为Employee类重写这些方法,HashSet只能看到两个Employees共享同一个实例时才相等。

要解决您的问题,您需要覆盖hashCode课程中的equalsEmployee方法。