TreeSet содержит / удалить не работает?
Я храню объекты Node в 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 ответа
Как выяснил Энди, ваша проблема заключалась в том, что вы изменили идентификатор своих элементов после вставки.
При использовании любого набора, вы должны позаботиться о том, чтобы не изменять элементы, пока они находятся в наборе. Из документации интерфейса Set:
Примечание. Необходимо соблюдать осторожность, если в качестве элементов набора используются изменяемые объекты. Поведение набора не указывается, если значение объекта изменяется таким образом, что это влияет на сравнение равных, в то время как объект является элементом в наборе.
То же самое относится и к ключам карты, и вы найдете эквивалентное утверждение в документации интерфейса карты.
В TreeSet (и используемом им лежащем в основе TreeMap) результат из compareTo
Метод используется для размещения, а затем найти элементы. Если результаты compareTo
изменился между вставкой и поиском, вероятно, он не будет работать должным образом.
Я менял значение идентификатора после его вставки в TreeSet, как предложил Энди. Я предполагаю, что это привело к неправильной сортировке узла.
Это работает сейчас, спасибо!