Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TreeSet contains/remove not working? [closed]

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?

like image 978
Casey Avatar asked Oct 20 '25 15:10

Casey


1 Answers

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.

like image 85
Erik Vesteraas Avatar answered Oct 23 '25 05:10

Erik Vesteraas



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!