美文网首页程序员开发经验随笔码农的世界
九成的人会答错的HashMap阈值问题

九成的人会答错的HashMap阈值问题

作者: 山东大葱哥 | 来源:发表于2019-06-28 08:38 被阅读27次

    问题

    JDK1.7中一个HashMap中是否会出现size>threshold情况?

    背景知识

    了解HashMap的同学都知道,HashMap中有几个重要的字段:

    • 负载因子loadFactor,指哈希表在其容量自动增加之前可以达到多满的一种尺度
    • 容量 capacity ,也就是当前table数组的长度
    • 阈值threshold,用于判断是否需要调整HashMap的容量(rehashing),阈值=capacity * load factor
    • 大小size,即HashMap存储的键值对数量

    HashMap扩容的条件

    关于扩容条件很多资料说的都是在size超过阈值时,就会触发扩容,以减少冲突的发生。
    但我在这里告诉大家,这个说法是错误的或者是不准确的。我们直接看jdk1.7中HashMap的源代码:

        void addEntry(int hash, K key, V value, int bucketIndex) {
            //判断已经存在的Entry数量是否超过了实际可容纳量、当前节点是否发生hash碰撞。
            if ((size >= threshold) && (null != table[bucketIndex])) {
                //如果超过阈值并且即将发生hash碰撞,则进行resize
                resize(2 * table.length);
                //重新计算hash
                hash = (null != key) ? hash(key) : 0;
                //重新计算索引位置
                bucketIndex = indexFor(hash, table.length);
            }
            //创建Entry节点对象
            createEntry(hash, key, value, bucketIndex);
        }
    

    看到其中的if条件是,与,两个条件都满足才进行resize:

    • size大于等于阈值
    • 当前节点发生hash碰撞

    所以如果只是size超过了阈值,而当前节点不发生碰撞的话,还是可以继续在原数组中存储数据的,因此就会出现下图的情况:


    image.png

    size=14 超过了 threshold=12 的阈值。

    相关文章

      网友评论

        本文标题:九成的人会答错的HashMap阈值问题

        本文链接:https://www.haomeiwen.com/subject/ymdlcctx.html