2010-09-17 25 views
4

我有以下代碼:如何排序設置不是唯一的數據?

public class EnglishWord implements Comparable<EnglishWord> { 

    private String word;// unique 
    private int occurenceNumber; //not unique 


    public EnglishWord(String word, int occurenceNumber) { 
     this.word = word; 
     this.occurenceNumber= occurenceNumber; 
    } 

    public boolean equals(EnglishWord anotherWord) { 
     return word.equals(anotherWord.getWord()); 
    } 

    public int compareTo(EnglishWord anotherWord) { 
     return occurenceNumber - anotherWord.getOccurenceNumber; 
    } 

我要添加的所有EnglishWord S IN的Set那裏的每一個獨特的word只有一個EnglishWord對象。我想要SetoccurrenceNumber排序。我已經將代碼按occurrenceNumber排序,但不會將EnglishWord與唯一的occurrenceNumber加到Set。作爲代碼,這裏是我的意思是:

Set<EnglishWord> mySet= new TreeSet<EnglishWord>(); 
mySet.add(new EnglishWord("hello",8)); 
mySet.add(new EnglishWord("hi",8)); 

在此之後,mySet的大小爲1

+0

其不清楚,請舉例說明。 – 2010-09-17 16:17:10

+0

恐怕很難理解你的問題。你可以嘗試進一步解釋,理想情況下與樣本數據? (輸入和期望輸出)? – 2010-09-17 16:17:56

+0

@Jon:我重寫了這個問題,儘管*「with unique occurrenceNumber to the Set」*部分仍然令我感到困惑。 – Esko 2010-09-17 17:25:54

回答

4

您應該既定義equals和hashCode,也不要定義它們。在你的代碼中,對於EnglishWord的兩個實例x和y,它會發生x.equals(y) == truex.hashCode() != y.hashCode()。如果您希望您的類使用java.util的集合類,那麼這是不合法的。見the Object JavaDoc。爲了解決這個問題,添加如下內容:

@Override 
public int hashCode() { 
    return this.word.hashCode(); 
} 

equals方法必須有簽名「公共布爾等於(對象除外)」 - 您的平等需要一個EnglishWord參數,導致你的方法被忽略本質。修復:

@Override 
public boolean equals(Object other) { 
    if (other == null) return false; 
    if (other.getClass() != this.getClass()) return false; 
    final EnglishWord ow = (EnglishWord) other; 
    return ow.word.equals(this.word); 
} 

一般來說,使用@Override註釋可以有很大的幫助,使您的編碼針對這種錯誤的更穩健的運行時錯誤變成一個編譯時錯誤這樣。

此外,您的Comparable接口的實現應該可能使用泛型。

4

你可能想通過occurenceNumber進行比較,如果是0,然後通過文字

比較
public int compareTo(EnglishWord anotherWord) { 
    int val = occurenceNumber.compareTo(anotherWord.occurenceNumber); 
    if (val == 0){ //ok, these have the same occurence, but are they the same word? 
     val = word.compareTo(other.word); 
    } 
    return val; 
} 
1

TreeSet內部支持TreeMapTreeMap.put(Object, Ojbect)將在您的EnglishWord上使用compareTo方法來確定新元素在樹中的位置。如果compareTo的結果爲0,則該方法假定元素相等。

這多少受到的JavaDoc矛盾爲TreeSet.add

再添設置 指定的元素到這一點,如果它不是已存在。如果該集合不包含 元素e2(e == null? e2 == null:e.equals(e2)),則正式添加指定元素e 。如果此集合 已包含該元素,則呼叫 會使該集合保持不變並返回 false。

Comparable的JavaDoc的說

強烈建議,但並不嚴格要求(則x.compareTo(Y)== 0)==(x.equals(Y))。一般來說,任何實現了Comparable接口並違反這個條件的類都應該清楚地表明這個事實。推薦的語言是「注意:這個類的自然排序與equals不一致」。

你需要採取這個建議,並比較相同的發生時的話。

0

一個集合只能有一個索引和一個排序。你想要的是兩個indecies,一個確保單詞是唯一的,第二個按發生次數排序。

要做到這一點,你需要維護兩個集合,一個集合,一個字爲唯一性鍵,另一個按發生和單詞排序。

注意:以這種方式在集合中使用的字段不能更改,否則您將得到不正確的行爲。我建議你讓田地最後。