How to make java HashMap work with custom key type?

I think my question is quite simple, however I could not find a solution, so I decided to ask here. I need to make a HashMap with a custom Key type like this:

HashMap<Pair<Integer, Integer>, StrategyPoint> myMap = new HashMap<Pair<Integer, Integer>, StrategyPoint> (); 

However, I don’t see something here because the HashMap stops working properly. First, the key becomes unique, and in the key set you can find different instances of the pair with the same values. Also, the key-key function does not work the way I assume it is :). I explicitly missed something, and most likely I need to somehow figure out how to compare my instances with my Pair class. However, I tried to implement Comparable with compareTo in the Pair class and still does not work. Any suggestions?

My source code is a bit dirty and unfriendly to read, so I made an example to illustrate my problem here. Here is the code:

 HashMap<Pair<Integer, Integer>, StrategyPoint> myMap = new HashMap<Pair<Integer, Integer>, StrategyPoint> (); Pair<Integer, Integer> myPair = new Pair<Integer, Integer>(2,2); StrategyPoint myPoint= new StrategyPoint(2, 2, 5, 5, false); myMap.put(myPair, myPoint); Pair<Integer, Integer> searcher = new Pair<Integer, Integer> (0,0); searcher.setFirst(2); searcher.setSecond(2); System.out.println(myMap.containsKey(searcher)); System.out.println(myMap.containsKey(myPair)); 

Execution Result:

falsely

True

I am debugging it and the crawler instance is populating properly, however it seems that the HashMap refuses to find it in its KeySet.

Thanks for helping the guys!

+6
source share
3 answers

You must correctly implement equals and hashCode in the Pair class.

HashMap uses these methods to differentiate and hash the key class.

+12
source

You need to override equals in the Pair class. An implementation of this method determines how two Pair objects are considered equal.

And whenever you redefine equals , you should always redefine hashcode .

Here's what could go wrong if you override equals but not hashcode (from Effective Java, Second Ed.):

Two different instances can be logically equal according to the equals classes, but for the hashCode method of objects, theyre only two objects that have nothing in common. Therefore, the hashCode method method returns two seemingly random numbers instead of two equal numbers in accordance with the requirements of the contract.

Since the hash codes for two logically equal instances become unequal, if you try to search one by one and the other in a collection, you will end up in the wrong hash bucket, which leads to null .

There is a set of rules that the equals implementation must comply with. Another set of rules for hashcode overrides.

+5
source

Your pair's class should implement hashCode() and equals() according to the contract specified in the Javadoc for Object .

+2
source

All Articles