【发布时间】:2018-04-26 01:44:50
【问题描述】:
AFAIK 因为 java 8 桶结构从链表更改为树。
所以如果 hashCode() 方法返回常量并且我们的关键类实现 Comparable 接口,那么从单个单元格获取元素的复杂度将从 O(n) 降低到 O(log n)。
我试着检查一下:
public static void main(String[] args) {
int max = 30000;
int times = 100;
HashMap<MyClass, Integer> map = new HashMap<>();
HashMap<MyComparableClass, Integer> compMap = new HashMap<>();
for(int i = 0; i < max; i++) {
map.put(new MyClass(i), i);
compMap.put(new MyComparableClass(i), i);
}
long startTime = System.nanoTime();
for (int i = max; i > max - times; i--){
compMap.get(new MyComparableClass(i));
}
System.out.println(String.format("Key is comparable: %d", System.nanoTime() - startTime));
startTime = System.nanoTime();
for (int i = max; i > max - times; i--){
map.get(new MyClass(i));
}
System.out.println(String.format("Key isn't comparable: %d", System.nanoTime() - startTime));
}
MyComparableClass:
public class MyComparableClass
implements Comparable {
public Integer value;
public MyComparableClass(Integer value) {
this.value = value;
}
@Override
public int compareTo(Object o) {
return this.value - ((MyComparableClass) o).value;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MyComparableClass myClass = (MyComparableClass) o;
return value != null ? value.equals(myClass.value) : myClass.value == null;
}
@Override
public int hashCode() {
return 1;
}
}
MyClass 与 MyComparableClass 相同,但没有实现 Comparable 接口。
而且出乎意料的是,我总是得到结果,其中通过不可比较的键获得价值的时间比通过可比较的要少。
Key is comparable: 23380708
Key isn't comparable: 10721718
谁能解释一下?
【问题讨论】:
-
你是如何在
MyClass中实现hashCode的? -
(1) 避免使用原始类型:
public class MyComparableClass implements Comparable<MyComparableClass>(2) 你的基准有缺陷(没有足够的迭代,没有预热等)阅读:stackoverflow.com/questions/504103/…。 -
@Eran MyClass 与 MyComparableClass 相同,但没有实现 Comparable 接口。
-
@assylias 看似通用的
compareTo方法根本没有使用。显式设置类有很大帮助。
标签: java java-8 hashmap hashtable