2014-10-20 62 views
0

執行比較我有這樣的和平代碼:元素後取出在TreeSet中

final SortedSet<NisType> lAllNNisType = new TreeSet<NisType>(new NisTypeComparator()); 
lAllNisType.addAll(pAllNisType); // where pAllNisType is of type ArrayList<NisType> 

這就是我比較類:

private class NisTypeComparator implements Comparator<NisType> { 

    @Override 
    public int compare(NisType pNisType, NisType pNisType2) { 
     if (pNisType.getPrio()>pNisType2.getPrio()) 
     return 1; 
     else if (pNisType.getPrio()<pNisType2.getPrio()) 
     return -1; 
     else 
     return 0; 
    } 
    } 

我的ArrayList pAllNisType充滿了6個不同的對象(基於平等和hashCode方法)。 後然而這一行被執行:

lAllNisType.addAll(pAllNisType); 

lAllNisType只包含5個對象。 有一個比較返回0.並且由於這一個對象已從lAllNisType中刪除。

我不知道這裏發生了什麼。 對象不同。如果我做這樣的事情:

final Set<NisType> lAllNisType = new HashSet<NisType>(pAllNisType); 

lAllNisType有6個元素。

感謝您的幫助

斯特凡

+1

然後你的'比較器'比較不同於'equals'和'hashCode'。當然是 – 2014-10-20 15:18:51

+0

。爲什麼這很重要? – 2014-10-20 15:20:22

+0

這就解釋了爲什麼你在'TreeSet'中有5個元素,而在'HashSet'中有6個元素。 – 2014-10-20 15:20:56

回答

1

是的,這恰恰表現爲documented.

注意,排序由有序集合維護(無論是否提供了明確的比較器)如果有序集合要正確實現Set接口,則必須與equals保持一致。 (請參見Comparable接口或Comparator接口以獲得與equals一致的精確定義。)這是因爲Set接口是根據equals操作定義的,但排序集使用它的compareTo(或compare)方法執行所有元素比較,,所以從排序集的角度來看,通過這種方法被認爲相等的兩個元素等於。即使排序與等號不一致,排序集的行爲也是很好定義的;它只是不服從Set接口的總體合同。

如果compare返回0,那麼就集合而言,兩個元素被認爲是相等的,並且只有其中一個元素可以出現在集合中。如果你想保留這兩個對象,你需要讓你的比較器區分它們,例如通過二次訂購。