[英]Java 8 Hashmap Internals
我已经完成了 Java 8 Hashmap 的实现,并带着以下疑问来到这里。 请帮我澄清一下:
但是当我看到源代码时,新节点被添加到尾部。 那是对的吗?
在旧版本中,它被添加到头部。 但是,在 Java 8 中进行了许多更改。
class A {
static class SameHash {
final int n;
SameHash(int n) {
this.n = n;
}
@Override
public int hashCode() {
return 1;
}
@Override
public String toString() {
return "SameHash{" +
"n=" + n +
'}';
}
}
public static void main(String[] args) {
HashSet<SameHash> set = new HashSet<>();
for (int i = 1; i <= 4; i++)
set.add(new SameHash(i));
System.out.println(set);
}
}
印刷
[SameHash{n=1}, SameHash{n=2}, SameHash{n=3}, SameHash{n=4}]
注意:键可以有不同的哈希码,但最终可以在同一个存储桶中。
我没有完全理解这个变量 MIN_TREEIFY_CAPACITY。 是不是经过这么多计数,整个地图将被转换为树(从数组到树)?
在此计数之后,如果键为Comparable
,则桶将转换为树
Peter Lawrey 对 MIN_TREEIFY_CAPACITY 的回应是错误的。
此常量默认为 64,并在 java.util.HashMap#treeifyBin 方法中使用,如果存储桶的大小大于 8 (TREEIFY_THRESHOLD),则会调用该方法。
在 java.util.HashMap#treeifyBin 方法中,如果哈希表大小小于 64,则整个表被 RESIZED - 加倍,否则,所讨论的桶是 TREEIFIED - 桶的 DS - 链表被转换为二叉树。
重点是保持 O(1) 插入或查找 - 如果哈希表大小很小(64),我们可以通过加倍轻松调整它的大小,因此存储桶的范围将加倍,并且哈希冲突会更少钥匙和每个桶将有更少的项目。
如果表大小大于 64,那么将哈希表大小加倍可能会很昂贵,最好只是将当前存储桶的链表转换为搜索速度更快的二叉树存储桶(链表搜索是 O(n ) 而二叉树搜索是 O(log(n))。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.