2014-07-09 44 views
0

我有兩套我的代碼,並在他們我添加相同的元素集合。問題是,TreeSet不會添加所有元素。我感到有點困惑。TreeSet不添加所有元素和HashSet

我現在有一個問題,我正在努力找出爲什麼我的TreeSet不會添加我傳遞給addAll的Collection中的所有元素。

這是一個TreeSet建立了比較,對於有項目的equals方法,如:

public final boolean equals(Object o) { 
    return this==o; 
} 

@Override 
public int hashCode() { 
    int hash = 3; 
    hash = 67 * hash +  Objects.hashCode(this.grauDeAdaptacao); 
    hash = 67 * hash + Objects.hashCode(this.idade); 
    return hash; 
} 

只是爲了測試我做了以下內容:

HashSet<Item> test1 = new HashSet<>(items); 
TreeSet<Item> test2 = new TreeSet<>(getComparator()); 
test2.addAll(items); 
if (test1.size() < 50 || test2.size()<50) { 
    throw new IllegalStateException(); 
} 

和比較器用途:

private int compare(S ser1, S ser2) { 
    return ser1.getGrau().compareTo(ser2.getGrau()); 
} 

但有什麼尷尬的是,哈希接縫很好,而TreeSet沒有全部50元素。

我需要兩個相同的元素,就像它們在所有子類中是相同的實例一樣,這就是爲什麼我做了這樣的最終方法。

+2

爲什麼比較器不使用其輸入?請顯示一個簡短但完整的*程序來證明問題? –

+0

爲什麼你重寫'equals'但不改變行爲......而你*是*改變'hashCode()'的行爲?基本上它是完全不清楚你想要達到什麼...... –

+0

它使用,很抱歉..只是一秒 – Victor

回答

2

A HashSet使用equals來測試兩個對象是否相等。

HashSet一個保證,它是從未的情況下,對於任何兩個不同的對象,並ab,在Seta.equals(b) == true

A TreeSet使用compareTo來測試兩個對象是否相等。

TreeSet保證,它是從未的情況下,對於任何兩個不同的對象,並ab,在Seta.compareTo(b) == 0

假設a.compareTo(b) == 0iffa.equals(b)那麼這種行爲是相同的。在這種情況下,可以說,compareTo方法是「用equals一致」,如documentation for Comparable

同一文檔還指出定義:

強烈推薦(雖然不要求)自然 排序與平等一致。這是因爲排序集 (和排序的地圖)沒有明確的比較行爲「奇怪」,當 它們與自然排序是 與等號不一致的元素(或鍵)使用。特別是,這樣的排序集合(或排序後的映射)違反了集合(或映射)的一般合同,該集合根據等號方法定義爲 。

這是一個奇怪地「行爲」的例子。

您的一些物品爲a.equals(b) == false但是a.compareTo(b) == 0

還應當指出的是,對於hashCode執行它需要,如果a.equals(b) == true然後a.hashCode() == b.hashCode()。在您的實施中,這是而不是。在執行equals時,您的hashCode()的實施無效。

反身財產是不是必需的。即它可以(並且將會)是a.hashCode() == b.hashCode()a.equals(b) == false的情況。

所以,總結。

  1. 您的hashCodeequals是錯誤的。它們需要保持一致,如equalshashCode的文檔中所述。
  2. 您的comapreTo是錯誤的,它應該與「equals」一致,如documentation for Comparable中所述。
+0

我喜歡當我進入「奇怪行爲」類別。=) – Victor

+0

但是現在我有一個尷尬的情況,因爲比較器應該按照'grau'屬性來排序元素,但它們不應該被認爲是等同的。 – Victor

+0

那麼不要使用'Set',使用'Collections.sort'來產生一個穩定的'List','Set'保證唯一性 –

0

解決,與您的幫助當然。 由於我需要一個數據結構,它可以高效地插入和搜索,而它總是會被排序 - 而不是從Java SE API中進行排序。 TreeSet太簡單了,不能使用它。所以我調整了比較器和項目以使用ID。就像樹快樂起來一樣,它將我的元素與我預期的屬性相關聯,如果它們相同,則ID將決定順序......它與平等相容,並且每個人都很高興。