Java JDK 8中的hashmap是否会在bucket中的条目对象从阈值减少后重新调整自身大小。?
我看到一个博客,其中JDK8给出了hashmap的更改和性能改进 从JDK1.8开始,HashMap引入了一种改进的策略来处理高冲突率。由于一个糟糕的哈希函数(例如总是返回同一个bucket的位置)可以将HashMap转换为链表,即将get()方法转换为在O(n)而不是O(1)中执行,并且有人可以利用这一事实,Java现在在内部将链表替换为二进制true,一旦超过某个阈值。这确保了性能或顺序O(log(n)),即使在哈希函数未正确分配密钥的最坏情况下也是如此 在JDK 8中,我们都知道,每当达到阈值时,链表就会将其自身重新调整为二叉树。我想知道当节点数小于阈值数时,二叉树是否会将自身重新调整为链表 在一次采访中,我问它:不会,因为它不会在每次数量发生变化时都重新调整自己的规模。我说得对吗 供参考的博客:Java JDK 8中的hashmap是否会在bucket中的条目对象从阈值减少后重新调整自身大小。?,java,dictionary,linked-list,hashmap,binary-search-tree,Java,Dictionary,Linked List,Hashmap,Binary Search Tree,我看到一个博客,其中JDK8给出了hashmap的更改和性能改进 从JDK1.8开始,HashMap引入了一种改进的策略来处理高冲突率。由于一个糟糕的哈希函数(例如总是返回同一个bucket的位置)可以将HashMap转换为链表,即将get()方法转换为在O(n)而不是O(1)中执行,并且有人可以利用这一事实,Java现在在内部将链表替换为二进制true,一旦超过某个阈值。这确保了性能或顺序O(log(n)),即使在哈希函数未正确分配密钥的最坏情况下也是如此 在JDK 8中,我们都知道,每当达到
这是
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;
所以问题的答案是“是”和“不是”。当大小下降到同一阈值以下时,它不会调整自身大小,但当它下降到不同阈值以下时,它会调整大小
我不明白为什么在面试中会问你这个问题——你申请的公司真的希望你记住Java库的源代码吗?这是
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;
所以问题的答案是“是”和“不是”。当大小下降到同一阈值以下时,它不会调整自身大小,但当它下降到不同阈值以下时,它会调整大小
我不明白为什么在面试中会问你这个问题——你申请的公司真的希望你记住Java库的源代码吗?在调整大小或删除过程中,存在于单个bin/bucket中的二进制树节点将被取消。但是,如果删除关联的映射元素,内部表的容量、阈值和总大小将不会缩小。
注意:Java8forwardHashMap正在使用位运算符实现2的扩展能力,以保持基本操作的恒定时间性能。每当贴图大小超过阈值时,它都会进行重新灰化。在此调整/扩展过程中,存储箱中的树将拆分为loBit/hiBit树&如果太小,将hiBit节点头移动到新的表索引,以两个偏移量的幂次移动。单个存储箱/存储桶中的二进制树节点将在调整大小或删除过程中被取消。但是,如果删除关联的映射元素,内部表的容量、阈值和总大小将不会缩小。
注意:Java8forwardHashMap正在使用位运算符实现2的扩展能力,以保持基本操作的恒定时间性能。每当贴图大小超过阈值时,它都会进行重新灰化。在此调整/扩展过程中,bin中的一棵树将被拆分为loBit/hiBit树&如果太小,则取消对同一棵树的搜索,将hiBit节点头移动到新的表索引,并以两个偏移量的幂次移动。正如答案所提到的,面试问题非常奇怪,因为您必须看到实际的源代码才能知道。正如答案所提到的,这个面试问题很奇怪,因为你必须看到实际的源代码才能知道。/我点头。。。偶尔,你会遇到一家公司,它认为“面试”是一个借口,要么“给你一个智商测试”,要么参与一个“琐碎的追求”的游戏,都是以你为代价的在任何这样的情况下,我都会毫不犹豫地直视提问者的眼睛,回答:“我不知道。”(不是:“对不起,但是……”。)#####现在,也许面试官只是想看看,“这个候选人有没有‘马的感觉’”,在这种情况下,“运用最佳判断。”问题说“在JDK 8中,我们都知道……”,但我要说的是,很少有人(相对而言)要知道,
HashMap
已经在Java 8中进行了优化,在一个散列桶后面使用一个二叉树,以在罕见的高冲突情况下提高性能。更多人知道的是,HashMap
会随着映射的增长调整散列桶的数量,所以我认为OP可能误解了这个问题estion@ajb我们讨论了hashmaps及其内部实现,所以他可能已经考虑过了。但是,我想再次问一下,假设阈值是8,那么我做map.put()为了使同一个键的总节点数为9,它将重新调整自身大小为二叉树。如果我现在删除2个节点,使阈值数再次为7,它会重新调整大小为链表吗?如果我再添加2个节点,使其中的总节点数为9,它会继续调整自身大小吗???@Andreas我从来没有误解过q甚至我们之前的讨论也在我上面的评论中给出了ajb@dgupta3091你看了答案了吗?“untreify”的阈值是6,所以在它降到这么低之前它不会恢复到链表,那么为什么你问7,而这仍然明显高于阈值?另外,请不要再叫它“resize”,因为这不是一个调整大小的操作。它将哈希桶从使用链表实现切换到使用二叉树实现。改变的不是大小,而是实现。/me点头。。。时不时,你会遇到一家公司,它认为“面试”是一个借口,要么“给你一个智商测试”,要么参与一个“琐碎的追求”的游戏,无论是在你的办公室还是办公室