【发布时间】:2017-12-20 09:38:55
【问题描述】:
我知道在 Java 8 中 HashMap 已针对分布不佳的 hashCode 进行了优化。并且在超过阈值的情况下,它会将存储桶中的节点从链表重建为树。同样是stated,这种优化不适用于不可比较的键(至少性能没有提高)。在下面的示例中,我将 not Comparable 键放入 HashMap
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
class Main {
public static void main(String[] args) throws InterruptedException {
Map<Key, Integer> map = new HashMap<>();
IntStream.range(0, 15)
.forEach(i -> map.put(new Key(i), i));
// hangs the application to take a Heap Dump
TimeUnit.DAYS.sleep(1);
}
}
final class Key {
private final int i;
public Key(int i) {
this.i = i;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Key key = (Key) o;
return i == key.i;
}
@Override
public int hashCode() {
return 1;
}
}
但是检查堆转储显示节点被重新排列成树。
我的问题是,如果节点不会提高性能,为什么要在树中重建节点?在这种情况下,节点会根据哪些标准进行比较,以确定哪个键应该是右节点,哪个是左节点?
【问题讨论】: