4

I am keeping Node objects in a TreeSet:

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

Node looks like this:

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();
    }
}

However, when I try to remove nodes, they do not get removed, and the TreeSet thinks they are not in the set!!

Remove code:

    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);

Output:

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]

Why is this? I've implemented Comparable, shouldn't that be it?

Casey
  • 41
  • 4
  • 2
    Please show a small program demonstrating the problem. It works for me. – Alexis C. Apr 04 '15 at 22:18
  • Check the result of the remove operation. Also see what contains() says after the intended removal. And you confirmed that _node_ was inserted into the container? Noticed your output says the node is not contained which might explain the results you're seeing. – bvj Apr 04 '15 at 22:23
  • I was changing the value of ID after inserting it into the TreeSet! It works now, thank you Andy! – Casey Apr 04 '15 at 22:28

2 Answers2

3

As Andy figured out, your problem was that you changed the ID of your elements after insertion.

When using any kind of Set, you should take care not to change the elements while they are in the Set. From the Set interface documentation:

Note: Great care must be exercised if mutable objects are used as set elements. The behavior of a set is not specified if the value of an object is changed in a manner that affects equals comparisons while the object is an element in the set.

The same thing applies to Map keys, and you will find an equivalent statement in the Map interface documentation.

In TreeSet(and the underlying TreeMap that it uses) the result from the compareTo method is used to place and then later find the elements. If the results of compareTo has changed between insertion and lookup, it will probably not work as it should.

Erik Vesteraas
  • 4,675
  • 2
  • 24
  • 37
0

I was changing the value of ID after inserting it into the TreeSet, just as Andy suggested. I imagine this caused the node to get sorted incorrectly.

It works now, thank you!

Casey
  • 41
  • 4