Is it a bug that Java 8's HashMap misbehaves if the keys implement Comparable in a way that isn't consistent with equals? -
i know since java 8, if hashmap
has enough hash collisions, , keys implement comparable
, use balanced tree instead of linked list bin. can see, comparable
interface does not require compareto()
"consistent equals()
" (though recommended).
did miss something? seems new implementation allows hashmap
violate requirements of map
interface if keys happen have compliant, non-recommended comparable
implementation.
the following junit test exposes behaviour on openjdk 8u72:
import static org.junit.assert.*; import java.util.hashset; import java.util.set; import org.junit.test; class foo implements comparable<foo> // comment out fix test case { private final int bar; private final int baz; foo(int bar, int baz) { this.bar = bar; this.baz = baz; } public boolean equals(object obj) { // note ignores 'baz' return obj instanceof foo && bar == ((foo) obj).bar; } public int hashcode() { return 0; } public int compareto(foo o) { // inconsistent equals(), seems obey requirements of // comparable<foo> return integer.compare(baz, o.baz); } } public class footest { @test public void test() { set<foo> set = new hashset<>(); (int = 0; < 128; ++i) { set.add(new foo(i, 0)); } // fails if foo implements comparable<foo> asserttrue(set.contains(new foo(64, 1))); } }
it's not bug anywhere imo, in code behaving implementor expected - known result of unusual comparable
implementation. comparable
documentation:
it recommended (though not required) natural orderings consistent
equals
. because sorted sets (and sorted maps) without explicit comparators behave "strangely" when used elements (or keys) natural ordering inconsistentequals
. in particular, such sorted set (or sorted map) violates general contract set (or map), defined in terms ofequals
method.
now while isn't sorted set or map in normal sense, there's clear relationship issue.
i agree it's possible issue though, , really subtle one, particularly it'll hard reproduce in simple situations. update documentation draw strong attention fact class implements comparable
in way inconsistent equals
, , refer potential issue.
Comments
Post a Comment