2013-01-10 28 views
2

我想利用一個獨特的java集合,它可以接受確定成員對象在集合初始化時是否「相等」的策略。支持自定義唯一性標準的現有Java集合?

我需要這樣做的原因是因爲我需要添加到此集合的類的equals方法已經實現以滿足其他(更合適的)功能。在特定情況下,此集合實例中唯一性標準需要僅檢查該類的一個變量,而不是在equals方法中檢查的多個變量。我寧願避免裝飾物體,因爲我正在從不同的圖書館收集它們,並且爲了裝飾而循環(並且可能使我的代碼渾濁)成本高昂。

我意識到這不會是一個設置,因爲它會打破Java contract for Set,但我只是覺得這個問題以前一定遇到過。我想GuavaApache Collections會提供一些東西,但似乎沒有運氣。 有沒有人知道任何可用的庫提供這種類型的功能?我應該一起娛樂一個不同的解決方案嗎?

+3

你爲什麼不只是使用包裝類和古典'Set'?或者這不是一個選擇? – fge

+2

番石榴[明確拒絕了這個想法](https://code.google.com/p/guava-libraries/issues/detail?id=576)。 –

+0

@fge成員對象的包裝類?我解釋了問題。 (儘管如此,我可能最終決定這是要走的路) – smp7d

回答

3

您可以使用自定義比較器和TreeSet或TreeMap嗎?或者使用密鑰有你的標準的地圖? HashSet只是一個HashMap的包裝器,所以使用地圖應該更加昂貴。

+0

我可以使用自定義比較器。我並沒有真正考慮過,因爲我一直認爲比較器是一種排序方式,我不需要。看看這些文檔,我發現TreeSet打破了Set合同。我想避免使用Map,因爲我概念上不需要Key-Value對。如果我決定實施自己的收藏集,我可以在內部使用地圖。 – smp7d

+0

你需要有一個自定義的想法,即對象的獨特之處。這是關鍵。您還想要保存原始對象不變。這是價值。有一個共同的租戶使用設置或列表與複雜的規則,而不是使用簡單的地圖。 –

1

這並不實際。考慮例如您認爲等效的類C的兩個實例。

現在你這樣做:

set.add(c1); 
set.remove(c2); 

如果設定後是空的?那麼.retainAll().removeAll()

你最好的賭注在這裏是爲了創建自己的類,它封裝了C類,deletages無論是需要被下放,並有包裝類實現.hashCode().equals()(也可能Comparable本身太)。有了這樣的課程,你可以繼續使用古典套裝和地圖。

1

番石榴有一個等價物,它可以讓你定義兩個物體是否相等。

它還具有Equivalence.Wrapper,它包裝任意對象,並將equals()和hashCode()委託給等價實現,而不是它們自己的實現。

所以你可以做這樣的事情:

public class MySet<T> implements Set<T> { 

    private final Equivalence<T> equivalence; 

    private final Set<Wrapper<T>> delegate = new HashSet<Wrapper<T>>(); 

    public MySet(Equivalence<T> equivalence) { 
     this.equivalence = equivalence; 
    } 

    public boolean add(T t) { 
     return delegate.add(equivalence.wrap(t)); 
    } 

    // other Set methods 

} 
+0

是的,我可以,並感謝您的實施。但是,沒有庫已經提供了這樣的實現嗎? – smp7d