Two different HashMap returning the same hashCode

80 Views Asked by At

I have two different sets of HashMap ({u=0, h=3} and {t=3, i=0}), and it is returning the same hashCode (224). I don't understand this, hashCode needs to be different for different objects, and here the HashMap contains different sets of key and value pairs, but it still returns the same hashCode. Can someone please explain how this works?

trying to get the hashcode of the hashmap in java

2

There are 2 best solutions below

3
Basil Bourque On

As Commented, your statement:

hashCode needs to be different for different objects

is incorrect.

A hash function takes an input, and returns a value derived from the input. The returned value is consistent. The same input always returns the same hash value.

However, two inputs can indeed coincidentally return the same hash value. This is known as a collision. One aspect of a good hash function is that collisions are unlikely. But collisions are always possible. Inputs are infinite but hash values are finite; so obviously collisions must be possible.

Let's test your assertion your two example maps result in the same hash value.

Map < String, Integer > mapX =
        new HashMap <> (
                Map.of (
                        "u" , 0 ,
                        "h" , 3
                )
        );

Map < String, Integer > mapY =
        new HashMap <> (
                Map.of (
                        "t" , 3 ,
                        "i" , 0
                )
        );

Map < String, Integer > mapZ =
        new HashMap <> (
                Map.of (
                        "Alphabet" , 7 ,
                        "Street" , 42
                )
        );

int hashX = mapX.hashCode ( );
int hashY = mapY.hashCode ( );
int hashZ = mapZ.hashCode ( );

Dump to console.

System.out.println ( "mapX = " + mapX );
System.out.println ( "mapY = " + mapY );
System.out.println ( "mapZ = " + mapZ );

System.out.println ( "hashX = " + hashX );
System.out.println ( "hashY = " + hashY );
System.out.println ( "hashZ = " + hashZ );

When run:

mapX = {h=3, u=0}
mapY = {t=3, i=0}
mapZ = {Alphabet=7, Street=42}
hashX = 224
hashY = 224
hashZ = 177047197

Indeed, both your maps result in the same value returned from hashCode: 224. Our third map results in a different hash value: 177,047,197.

If you want to know exactly why those particular inputs result in the same hash value, study the source code from OpenJDK.

0
Andy Turner On

You are perhaps misunderstanding the point of the hashCode() method.

hashCode() is a method that works in tandem with equals(Object):

  • equals(Object) is for telling you if two objects are definitely equal
  • hashCode() if for telling you if two objects are definitely not equal:
    • Two objects with different hashCode() values are definitely not equal
    • Two objects with the same hashCode() values may be equal

This might sound a bit odd: it's kinda vague to know if things aren't equal: you have to do something more to determine if they are equal (that is, use the equals(Object) method).

What's the point of having two methods, one vague, one precise, to determine equality?

Let's say you've got 1000 objects, and you want to know which ones are equal: armed only with the equals method, you've got to do a pairwise comparison between all of them, so, roughly 500000 comparisons.

Enter hashCode(): you can use the hash of each object to put them into buckets: there's no point in checking if objects with different hash codes are equals, because they won't be (assuming correct implementation of hashCode()). You only have to do 1000 bucket operations.

Maybe you end up with only one item in each bucket; maybe you end up with 5 things in one bucket; now, you only have to do 12 pairwise comparisons to find which ones are equal.

hashCode() is really an ugly internal implementation detail: it is only present in order to support HashMap, HashTable etc (as described in the Javadoc).

You shouldn't ever really care about or use its value. All equal objects will have the same value, but some unequal objects will also have the same value. hashCode() is a source of bugs because it needs to be implemented consistently with equals(Object), but there is no language-level support to ensure that consistency. In an ideal world, it wouldn't be visible to us.

Don't expect it to have any properties beyond what it's designed for.