2015-04-04 43 views
2

我保持Node對象在一個TreeSet:TreeSet包含/刪除不工作?

public TreeSet<Node> viewNodes = new TreeSet<Node>(); 

節點看起來是這樣的:

public class Node implements Comparable<Node>{ 
    private long nodeID; 
    ... 
    public long getID() { 
     return nodeID; 
    } 

    @Override 
    public int compareTo(Node n) { 
     System.out.println("comparing: " +this + " with " + n + " -- " + new Long(nodeID).compareTo(n.getID())); 
     return new Long(nodeID).compareTo(n.getID()); 
    } 

    @Override 
    public boolean equals(Object o){ 
     if(o instanceof Node){ 
      System.out.println((compareTo((Node)o) == 0)); 
      return compareTo((Node)o) == 0; 
     } 
     return false; 
    } 

    @Override 
    public int hashCode(){ 
     return new Long(nodeID).hashCode(); 
    } 
} 

然而,當我嘗試刪除節點,他們沒有得到去除,TreeSet的認爲他們不在集合中!

刪除代碼:

System.out.println("removing " + node); 
    System.out.println("viewNodes: " + viewNodes); 
    System.out.println("contains node?: " + viewNodes.contains(node)); 
    viewNodes.remove(node); 
    System.out.println("now viewNodes looks like: " +viewNodes); 

輸出:

removing 5 
viewNodes: [5, 4, 3, 2, 1] 
comparing: 5 with 2 -- 1 
comparing: 5 with 1 -- 1 
contains node?: false 
comparing: 5 with 2 -- 1 
comparing: 5 with 1 -- 1 
now viewNodes looks like: [5, 4, 3, 2, 1] 

這是爲什麼?我已經實現了Comparable,應該不是嗎?

+2

請顯示一個小程序來演示問題。這個對我有用。 – 2015-04-04 22:18:20

+0

檢查刪除操作的結果。另請參閱包含()在預期刪除後說的內容。你確認_node_被插入到容器中了嗎?注意到你的輸出說節點不包含這可能解釋你看到的結果。 – bvj 2015-04-04 22:23:07

+0

將ID插入TreeSet後,我改變了它的值!它現在有用,謝謝你安迪!作爲回答發佈了 – Casey 2015-04-04 22:28:01

回答

0

正如Andy所說,我在將ID插入TreeSet後改變了ID的值。我想這導致節點得到錯誤排序。

現在有用,謝謝!

+0

。 – 2015-04-04 22:38:49

2

正如Andy所想的那樣,您的問題在於您在插入後更改了元素的ID。

當使用任何類型的Set時,您應該注意不要在設置中更改元素。從Set interface documentation

注意:如果將可變對象用作set元素,必須非常小心。如果對象的值以影響等於比較的方式更改,而對象是集合中的元素,則不會指定集的行爲。

同樣的事情適用於Map鍵,您會在Map interface documentation中找到等價的語句。

在TreeSet(及其使用的底層TreeMap)中,使用compareTo方法的結果放置並稍後查找元素。如果compareTo的結果在插入和查找之間發生了變化,它可能無法正常工作。