2011-12-14 43 views
1

JavaDoc的定義設定爲:Java的設置得到重複條目

不包含重複元素的集合。更正式地,設置 不含對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

閱讀:http://www.amazon.com/Effective-Java-2nd-Joshua-Bloch/dp/0321356683 – Tom 2011-12-14 12:58:28

回答

7

您的Employee類不覆蓋hashCode - 它需要這樣做才能使任何基於散列的收集工作。

例如:

@Override 
public int hashCode() { 
    return id; 
} 
+0

您是否確實輸入了答案並在21秒內格式化?我放棄了:-) – crnlx 2011-12-14 13:00:17

+0

@crnlx:我的第一個版本沒有包含代碼示例。 – 2011-12-14 13:01:11

+0

這使事情變得更好一點。 – crnlx 2011-12-14 13:05:29

4

你的類voilates上equals()hashCode()合資合同:

注意,一般需要覆蓋hashCode方法每當equals方法被重寫,從而維護hashCode方法的一般合約,其中規定相等的對象必須具有相同的散列碼。

在你的情況,相等的對象不一定相等的散列碼。這是令人困惑的HashSet,因爲Employees與相同的id可能最終在不同的桶中,因此得到對待,如果他們不相等。

要修復,請覆蓋hashCode() [例如,僅返回this.id]。

0

也許這是您的問題return this.id - o.id;而您檢查return this.equals(o)返回true或false。

1

HashSet基於Hash Table數據結構,所以你必須覆蓋Employee類都equalshashCode方法,以使其正常工作。

但是,您可以使用不基於散列表的其他Set實現,如TreeSet