JDK 8 中的 hashmap 是否在桶中的条目对象从阈值减少后再次调整自身大小。?
Does hashmap in JDK 8 resizes itself again after the entry objects in a bucket decreases from the threshold.?
我看到一个博客,其中在 JDK8 中给出了 hashmap 的更改和性能改进。
From JDK 1.8 onwards HashMap has introduced an improved strategy to deal with high collision rate. Since a poor hash function e.g. which always return location of same bucket, can turn a HashMap into linked list, i.e. converting get() method to perform in O(n) instead of O(1) and someone can take advantage of this fact, Java now internally replace linked list to a binary true once certain threshold is breached. This ensures performance or order O(log(n)) even in the worst case where a hash function is not distributing keys properly.
在JDK8中,我们都知道,每当达到一个阈值时,链表就会重新调整自己的大小为二叉树。我想知道当节点数小于阈值时,二叉树是否会将自身重新调整为链表。?
在一次采访中有人问我,我回答说,不,因为每次数字发生变化时它都不会不断调整自己的大小。我说得对吗?
参考博客:
这是 HashMap
来源中评论的一部分:
* Because TreeNodes are about twice the size of regular nodes, we
* use them only when bins contain enough nodes to warrant use
* (see TREEIFY_THRESHOLD). And when they become too small (due to
* removal or resizing) they are converted back to plain bins.
再往下看,我看到了:
/**
* The bin count threshold for using a tree rather than list for a
* bin. Bins are converted to trees when adding an element to a
* bin with at least this many nodes. The value must be greater
* than 2 and should be at least 8 to mesh with assumptions in
* tree removal about conversion back to plain bins upon
* shrinkage.
*/
static final int TREEIFY_THRESHOLD = 8;
/**
* The bin count threshold for untreeifying a (split) bin during a
* resize operation. Should be less than TREEIFY_THRESHOLD, and at
* most 6 to mesh with shrinkage detection under removal.
*/
static final int UNTREEIFY_THRESHOLD = 6;
所以问题的答案是"yes and no"。当大小低于 相同 阈值时它不会自行调整大小,但当它低于不同的阈值时它会调整大小。
我不明白为什么面试会问你这个问题——你应聘的公司真的希望你记住Java库的源代码吗?
个体 bin/bucket 中存在的二叉树节点将在调整大小或删除过程中取消树化。但是,如果删除关联的地图元素,内部 Table 的容量、阈值和整体大小不会缩小。
注意:Java8以后HashMap使用按位运算符实现2的幂扩展,以保持基本操作的恒定时间性能。每当地图大小超过阈值时,它就会重新散列。在此 resize/expansion 期间,容器中存在的树将被拆分为 loBit/hiBit 树,如果树太小,则将相同的树分解,将 hiBit 节点头移动到新的 Table 索引,其值为两个偏移量
我看到一个博客,其中在 JDK8 中给出了 hashmap 的更改和性能改进。
From JDK 1.8 onwards HashMap has introduced an improved strategy to deal with high collision rate. Since a poor hash function e.g. which always return location of same bucket, can turn a HashMap into linked list, i.e. converting get() method to perform in O(n) instead of O(1) and someone can take advantage of this fact, Java now internally replace linked list to a binary true once certain threshold is breached. This ensures performance or order O(log(n)) even in the worst case where a hash function is not distributing keys properly.
在JDK8中,我们都知道,每当达到一个阈值时,链表就会重新调整自己的大小为二叉树。我想知道当节点数小于阈值时,二叉树是否会将自身重新调整为链表。?
在一次采访中有人问我,我回答说,不,因为每次数字发生变化时它都不会不断调整自己的大小。我说得对吗?
参考博客:
这是 HashMap
来源中评论的一部分:
* Because TreeNodes are about twice the size of regular nodes, we
* use them only when bins contain enough nodes to warrant use
* (see TREEIFY_THRESHOLD). And when they become too small (due to
* removal or resizing) they are converted back to plain bins.
再往下看,我看到了:
/**
* The bin count threshold for using a tree rather than list for a
* bin. Bins are converted to trees when adding an element to a
* bin with at least this many nodes. The value must be greater
* than 2 and should be at least 8 to mesh with assumptions in
* tree removal about conversion back to plain bins upon
* shrinkage.
*/
static final int TREEIFY_THRESHOLD = 8;
/**
* The bin count threshold for untreeifying a (split) bin during a
* resize operation. Should be less than TREEIFY_THRESHOLD, and at
* most 6 to mesh with shrinkage detection under removal.
*/
static final int UNTREEIFY_THRESHOLD = 6;
所以问题的答案是"yes and no"。当大小低于 相同 阈值时它不会自行调整大小,但当它低于不同的阈值时它会调整大小。
我不明白为什么面试会问你这个问题——你应聘的公司真的希望你记住Java库的源代码吗?
个体 bin/bucket 中存在的二叉树节点将在调整大小或删除过程中取消树化。但是,如果删除关联的地图元素,内部 Table 的容量、阈值和整体大小不会缩小。
注意:Java8以后HashMap使用按位运算符实现2的幂扩展,以保持基本操作的恒定时间性能。每当地图大小超过阈值时,它就会重新散列。在此 resize/expansion 期间,容器中存在的树将被拆分为 loBit/hiBit 树,如果树太小,则将相同的树分解,将 hiBit 节点头移动到新的 Table 索引,其值为两个偏移量