Search code examples
javaequalshashcodetreemapcomparable

Consistent Equals() results, but inconsistent TreeMap.containsKey() result


I have the following object Node:

    private class Node implements Comparable<Node>(){
         private String guid();

         ...

         public boolean equals(Node o){
             return (this == o);
         }

         public int hashCode(){
              return guid.hashCode();
         }

         public int compareTo(Node o){
            return (this.hashCode() - o.hashCode());
         }

         ...

    }

And I use it in the following TreeMap:

TreeMap<Node, TreeSet<Edge>> nodes = new TreeMap<Node, TreeSet<Edge>>();

Now, the tree map is used in a class called Graph to store nodes currently in the graph, along with a set of their edges (from the class Edge). My problem is when I try to execute:

   public containsNode(n){
        for (Node x : nodes.keySet()) {
            System.out.println("HASH CODE: ");
            System.out.print(x.hashCode() == n.hashCode());
            System.out.println("EQUALS: ");
            System.out.print(x.equals(n));
            System.out.println("CONTAINS: ");
            System.out.print(nodes.containsKey(n));
            System.out.println("N: " + n);
            System.out.println("X: " + x);
            System.out.println("COMPARES: ");
            System.out.println(n.compareTo(x));
            }
        }

I sometimes get the following:

HASHCODE: true EQUALS: true CONTAINS: false N: foo X: foo COMPARES: 0

Anyone have an idea as to what I'm doing wrong? I'm still new to all this, so I apologize in advance if I'm overlooking something simple (I know hashCode() doesn't really matter for TreeMap, but I figured I'd include it).

edit1: added compareTo() method information.


Solution

  • There are a couple of things wrong here.

    • You have not overriden Object.equals. Use @Override public boolean equals(Object obj).
    • There is a potential integer overflow error in compareTo. This is probably the cause of this particular error. It will upset the sorting, and hence the search may well not succeed.
    • The compareTo method claims two instances are equal if the hash code happens to match (could be a difficult error to catch, without code review).

    For integer overflow issue, see question Why is my simple comparator broken?