TreeMap does not work as expected

class Point{ int x, y, l; Point(int x, int y, int l){ this.x =x; this.y =y; this.l=l; } @Override public int hashCode() { return y; } @Override public boolean equals(final Object obj) { if(this == obj) return true; if(!(obj instanceof Point)) return false; Point p = (Point) obj; return this.x == px && this.y == py; } } TreeMap<Point,Integer> sortedMap = new TreeMap<>((p1, p2)-> p1.l-p2.l); sortedMap.put(new Point(4,5,0),0); sortedMap.put(new Point(5,5,0),6); System.out.println(sortedMap.size()); -> Output: 1 System.out.println((new Point(4,5,0)).equals(new Point(5,5,0))); -> Output -> False. 

I overloaded both hash codes equal to the method in the class. I think the put method should use the equals method to determine if the same object exits or not. But it does not work as expected.

I'm not sure why my hashMap size is 1 .. Please let me know if I realized that hashmap is not working properly. Help me identify an error in this code?

+5
source share
3 answers

Your TreeMap compares Point values ​​with part l (whatever it should be). What this part of your code does:

 new TreeMap<>((p1, p2)-> p1.l-p2.l); 

The two points you created have the same value l (0), so they are considered equal ... so the second call to put replaces the existing record. TreeMap does not use equals and hashCode .

In the documentation:

Please note that the ordering supported by the tree map, like any sorted map, as well as the presence of an explicit comparator, must be matched if this sorted map must correctly implement the map interface. (See Comparable or Comparator for an exact definition of matching with peers.) This is because the Map interface is defined in terms of the operation with equal values, but the sorted map performs all key mappings using the compareTo (or comparison) method, so there are two keys that considered equal by this method, equal, in terms of sorted cards. The behavior of a sorted card is well defined, even if its order is not consistent with the equalities; he simply does not comply with the general contract of the map interface.

Your comparison does not match equals , so you see results that violate the Map contract.

+11
source

TreeMap uses only the supplied Comparator (or the natural order, when available) to determine equality, so equals and hashCode do not matter.

In your case, both Point have the same value of l , so they are considered identical according to your Comparator .

You can modify your Comparator to take into account all the properties ( l , x and y ) when determining the order (and equality) of your keys.

+5
source
 sortedSet.put(new Point(4,5,0),0); sortedSet.put(new Point(5,5,0),6); 

As a result of this call, use the supplied comparator ((p1, p2)-> p1.l-p2.l) to check if the two equal points match.

 (new Point(4,5,0)).equals(new Point(5,5,0)) 

In this case, the value overridden in the Point class is used.

Therefore, the difference.

+2
source

Source: https://habr.com/ru/post/1270430/


All Articles