7

I have a HashMap<Vertex, Integer> called vertexIndexes. If I iterate through it with this code:

public boolean search(String vertexName){
    for (Vertex name: vertexIndexes.keySet()){        
        String key =   name.toString();
        String value = vertexIndexes.get(name).toString();              
        System.out.println(key + " " + value + " "+ (name.hashCode() == vertexName.hashCode()) + " " + name.equals(vertexName));  
    }
...
}

it produces this output:

Diessen 0 false false
Herrsching 5 false false
Schondorf 2 false false
Greifenberg 3 false false
Stegen 4 false false
Utting 1 false false
Andechs 6 false false
Fischen 7 true true

So you can see, that the Vertex Fischen is present and the hashCode and equals methods work fine. But if I run

vertexIndexes.containsKey("Fischen")

it returns false.

Why is that? I lose my mind over it.

Eran
  • 359,724
  • 45
  • 626
  • 694
gutenmorgenuhu
  • 2,211
  • 1
  • 16
  • 33
  • 13
    So the keys are instances of `Vertex`, not of `String`? But the key you are checking for is a `String`. A `String` will never be equal to anything but another `String`. – khelwood Mar 26 '19 at 10:03
  • As you can see in my output (..true true..): I implemented the toString() and equals method of Vertex to correctly compare it to a String. – gutenmorgenuhu Mar 26 '19 at 10:05
  • 9
    `toString()` is irrelevant, and even if your `Vertex` instance claims to be equal to a `String`, the `String` instance will _not_ say it is equal to a `Vertex`. – khelwood Mar 26 '19 at 10:06
  • @khelwood unless in a very alternative implementation of an equals method :) – Stultuske Mar 26 '19 at 10:08
  • 1
    Possible duplicate of [What issues should be considered when overriding equals and hashCode in Java?](https://stackoverflow.com/questions/27581/what-issues-should-be-considered-when-overriding-equals-and-hashcode-in-java) – Lino Mar 26 '19 at 10:10
  • You key types are different. Your maps keyset is of type Vertex and you are passing string to contains method of map. – Oomph Fortuity Mar 26 '19 at 11:16

1 Answers1

41

name.equals(vertexName) compares a Vertex to a String. While your Vertex class equals method might return true when you pass a String to it, String's equals will never return true when you pass a Vertex to it.

HashMap probably tests whether vertexName.equals(name), which returns false.

Change

vertexIndexes.containsKey("Fischen")

to

vertexIndexes.containsKey(new Vertex("Fischen"))

or change the key of your Map to String.

BTW, you could have avoided that issue in the first place if you followed the contract of the equals method that appears in the Javadoc of the Object class:

• It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.

Your equals implementation is not symmetric.

Eran
  • 359,724
  • 45
  • 626
  • 694