Java Set获取重复条目

时间:2011-12-14 12:55:56

标签: java collections set unique hashset

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));将对象添加两次。

我的代码出了什么问题?

4 个答案:

答案 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中的hashCodeEmployee方法才能使其正常运行。< / p>

但是,您可以使用不基于哈希表的其他Set实现,例如TreeSet

答案 3 :(得分:0)

也许这是您的问题return this.id - o.id;,而不是检查return this.equals(o)返回true或false。