2016-05-23 18 views
1

我有一個我想放在TreeSet中的類,它實現了Comparable來按優先級對它們進行排序。下面是一小部分:從Java TreeSet中消失的對象

public abstract class PacketListener implements Comparable<PacketListener> { 
    public enum ListenerPriority { 
     LOWEST, LOW, NORMAL, HIGH, HIGHEST 
    } 

    private final ListenerPriority priority; // Initialized in constructor 

    // ... class body ... 

    @Override 
    public final int compareTo(PacketListener o) { 
     return priority.compareTo(o.priority); 
    } 
} 

的想法顯然是爲TreeSet爲優先對象進行排序,讓我通過監聽器,以便進行迭代。但是,我發現由於某種原因,我無法在設置的對象上添加第二個PacketListener。在添加兩個不同的對象後,該組的大小保持爲1.

我不應該使用TreeSet

回答

3

The API docs for TreeSet包含這些重要的信息:

注意,由一組(無論是否提供了明確的比較器)保持的順序必須是符合等於如果是要正確實現Set接口。 [012]這是因爲Set接口是根據equals操作定義的,但TreeSet實例使用其compareTo(或compare)方法執行所有元素比較,因此通過此方法認爲相等的兩個元素是,從集合的角度來看,平等。

換句話說,一個TreeSet可容納您PacketListener類的多個實例,但只只要各自具有比所有其他不同的優先級,從而爲每對元件 ,其中恰好有一個是:A == BA.compareTo(B) != 0

如果在同一個集合中必須容納多個具有相同優先級的PacketListener實例,則需要使用不同類型的集合。 HashSet對於使用從Object繼承的equals()hashCode()方法的類來說是非常好的,前提是這確實是期望的實例相等感。如果您想要對迭代順序進行某種保證,您也可以考慮使用LinkedHashSet,如果您想按優先順序排序但您願意使用其他機制來避免重複,則可以使用PriorityQueue

1

TreeSetcompareTo返回0的兩個對象視爲等於。這意味着你將永遠不會在你當前的實現中擁有與你的樹集合中相同優先級的兩個對象。

解決您的問題的方法是讓您的compareTo方法考慮您關心的所有值(即只有實際相等的對象返回0)。

0

A Set是獨特元素的集合。由於您使用優先級來比較PacketListener,因此我假定您最多隻有五個實例TreeSet,每個優先級一個。

如果結構允許,您可以找到一個輔助鍵來比較PacketListener,以防它們具有相同的優先級。如果你不能,那麼TreeSet是錯誤的路要走。