Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JDK 8中的hashmap是否会在bucket中的条目对象从阈值减少后重新调整自身大小。?_Java_Dictionary_Linked List_Hashmap_Binary Search Tree - Fatal编程技术网

Java JDK 8中的hashmap是否会在bucket中的条目对象从阈值减少后重新调整自身大小。?

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中,我们都知道,每当达到

我看到一个博客,其中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点头。。。时不时,你会遇到一家公司,它认为“面试”是一个借口,要么“给你一个智商测试”,要么参与一个“琐碎的追求”的游戏,无论是在你的办公室还是办公室