2014-02-06 45 views
4

我正在尋找一個Set類,它將使用給定的比較器removeAll()。替代在java中使用TreeSet?

我用TreeSet的,但幾個小時撕裂了我的頭髮試圖想通了,爲什麼我的removeAll()並沒有刪除任何我發現這之後...

http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4730113

長話短說的removeAll( )使用equals()方法。 (但奇怪的是,remove()方法不...)

我確實想要一個刪除重複項的設置,最好使用比較器但不是必需的,我不能重寫equals方法b/c我需要它爲其他邏輯。顯然,我想避免在所有元素上調用remove(),以免在將來(或其他人)混淆我的循環。

這樣的動物存在嗎?

+1

創建你自己的並將所有方法委託給樹集但刪除全部? – assylias

+0

也許你可以創建你自己的TreeSet衍生產品,它可以根據你的需要進行操作,並覆蓋一些方法? – h22

+0

我希望有一些東西存在,所以我不必那樣做。我看了一下java lib和apache commons,但他們似乎沒有(我可能錯過了它)。對我來說,TreeSet的行爲似乎仍然很奇怪。 – t014y

回答

0

TreeSet.removeAll方法接受Collection<?>作爲參數。集合中的對象可以是任何類型,不一定是Comparable對象。你需要用不同的方法制作你自己的Set。請注意,該錯誤解決方案「不會修復」

0

該行爲實際上非常合理。 '等於'確定兩個對象是否具有相同的身份,比較決定了發送給它們的某種形式的大小之間的關係。

兩個對象可以完全不同(等於返回false),但仍然具有相同的大小(例如考慮複數)。

您的期望是,removeAll將根據對象的「大小」(由比較定義)確定需要刪除的內容,您看到的是根據身份實際執行的刪除操作。

總之,使用循環:-)

0

您可以使用

public static <T> void removeAll(TreeSet<T> set, Collection<T> toRemove) 
{ 
    TreeSet<T> toRemoveTreeSet=new TreeSet<>(set.comparator()); 
    toRemoveTreeSet.addAll(toRemove); 
    set.removeAll(toRemoveTreeSet); 
} 

public static <T> void removeAll(TreeSet<T> set, Collection<?> toRemove) 
{ 
    for(Object o:toRemove) set.remove(o); 
} 
0

你有沒有覆蓋由TreeSet中包含的平等和對象的hashCode方法?