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, как предложил Энди. Я предполагаю, что это привело к неправильной сортировке узла.

Это работает сейчас, спасибо!

Другие вопросы по тегам