-
-
Notifications
You must be signed in to change notification settings - Fork 639
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improve hashCode() implementation for Tuple2 (#2803)
The current implementation of the hashCode() method for `Tuple2` has a significant flaw that can easily lead to hash collisions, particularly in data structures like `LinkedHashMap`. ```java LinkedHashMap<String, Integer> m1 = LinkedHashMap.of("a", 1, "b", 2); LinkedHashMap<String, Integer> m2 = LinkedHashMap.of("a", 2, "b", 1); System.out.println(m1.hashCode() == m2.hashCode()); // true ``` In this case, _m1_ and _m2_ should ideally produce different hash codes, but they don't. This is because the current implementation of `Tuple#hashCode()` simply sums the hash codes of all elements, which can result in identical hash codes for different tuples. A potential solution is to apply the XOR (^) operator to the hash codes of all elements. XOR is order-sensitive, so it would resolve the issue in the example above, where the order of elements differs between tuples. However, XOR has its limitations and is only a suitable solution for tuples with up to two elements. This is because XOR is a commutative and associative operation, meaning that the XOR of multiple elements can still result in rather bad collisions: ```java Tuple3<Integer, Integer, Integer> t1 = Tuple.of(1, 2, 3); Tuple3<Integer, Integer, Integer> t2 = Tuple.of(1, 3, 2); System.out.println(t1.hashCode() == t2.hashCode()); // true ``` The new implementation is not perfect as well: ```java HashMap<Integer, Integer> hm1 = HashMap.of(0, 1, 1, 2); HashMap<Integer, Integer> hm2 = HashMap.of(0, 2, 1, 3); System.out.println(hm1.hashCode() == hm2.hashCode()); // true ``` But it is imperfect in the same way as standard library: ```java java.util.HashMap<Integer, Integer> jhm1 = new java.util.HashMap<>(); jhm1.put(0, 1); jhm1.put(1, 2); java.util.HashMap<Integer, Integer> jhm2 = new java.util.HashMap<>(); jhm2.put(0, 2); jhm2.put(1, 3); System.out.println(jhm1.hashCode() == jhm2.hashCode()); // true ``` ---- Related: #2733
- Loading branch information
Showing
9 changed files
with
64 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters