Java8哈希映射内部
我已经完成了Java8HashMap的实现,并带着以下疑问来到这里。请帮我澄清一下:Java8哈希映射内部,java,hashmap,Java,Hashmap,我已经完成了Java8HashMap的实现,并带着以下疑问来到这里。请帮我澄清一下: 我在一篇文章中读到,使用相同哈希代码的节点 将添加到与链表相同的存储桶中。它说新的 此链表的节点将添加到head而不是tail中,以避免尾部遍历。 但当我看到源代码时,新的节点被添加到尾部。 对吗 我没有完全理解这个变量的最小树容量。经过这么多的计算后,整个映射是否会转换为树(从数组到树) 但当我看到源代码时,新的节点被添加到尾部。对吗 在旧版本中,它被添加到头部。然而,Java8中做了许多更改,而Java8没
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);
}
}
注意:键可以有不同的hashcode,但可以在同一个bucket中结束
我没有完全理解这个变量的最小树容量。经过这么多的计算后,整个映射是否会转换为树(从数组到树)
在此计数之后,如果密钥是可比较的,则桶将转换为树。Peter Lawrey关于最小树容量的响应是错误的 该常量默认为64,并在java.util.HashMap#treeifyBin方法中使用,该方法在bucket的大小大于8(TREEIFY#u阈值)时调用 在java.util.HashMap#treeifyBin方法中,如果哈希表大小小于64,则整个表的大小将调整一倍,否则,所讨论的bucket将被树化—bucket的DS链表将转换为二叉树 整个要点是保持O(1)插入或查找-如果哈希表大小很小(64),我们可以通过将其加倍来轻松调整大小,因此存储桶的范围将加倍,哈希键的冲突将减少,每个存储桶的项目也将减少
如果表的大小大于64,那么将哈希表的大小增加一倍的代价可能会更高,最好将当前bucket的链表转换为二叉树bucket,二叉树bucket的搜索速度更快(链表搜索为O(n),而二叉树搜索为O(log(n)).因此,在表大小达到64且bucket大小达到8后,该bucket将单独转换为tree right?或表中的所有bucket?正确,只有达到阈值的bucket将从节点(链表)转换为TreeNode(平衡/二叉树)。请记住,也有从树节点到节点的反向转换,当哈希表调整大小时,以及当一些大存储桶的大小小于untreefy_THRESHOLD=6时,就会发生这种情况
[SameHash{n=1}, SameHash{n=2}, SameHash{n=3}, SameHash{n=4}]