HashMap里的size属性到底指的是数组实际长度还是键值总数(JDK1.8)

在看这篇前需要了解以下几点

  • HashMap里的键值数一旦大于阈值,就会进行扩容
  • HashMap的底层数据结构是数组+链表+红黑树(JDK1.8)
  • HashMap相同hash值,但是equals结果不相等的键值对会在同一条单向链表或红黑树中

所以问题来了,这里所说的键值数大于阈值,这个键值数只是单纯的指在数组中(链表头的键值对)的键值数,还是指包含所有链表下键值对的所有键值数。

以下跟进源码做个测试:

测试代码:

public class TestMain {
    public static void main(String[] args) throws Exception {
        HashMap<String, String> map = new HashMap<>(3);
        map.put("1", "1");
        map.put("Aa", "11");
        map.put("BB", "66");
        int beforeSize = map.size();
        System.out.println(beforeSize);
        map.put("2", "6");
        int afterSize = map.size();
        System.out.println(afterSize);
    }
}

以上代码我初始容量设置为3,然后先向map里添加3条数据,其中key为Aa和BB的数据,他们的hash值是相同的,都是2112,所以这两条数据会在一个链表里,而之后再添加第4条数据,这时如果键值对数目为3,则需要扩容,如果键值对数目为2,则不会触发扩容操作。

直接找到判断扩容的代码,打上断点,这里的size就是我们要讨论的,而threshold就是阈值:
在这里插入图片描述

map.put(“1”, “1”)时,size原始值为0,++size,所以size变为1:
在这里插入图片描述
map.put(“Aa”, “11”)时,size原始值为1,++size,所以size变为2:

在这里插入图片描述
map.put(“BB”, “66”)时,发现"BB"的hashcode值和"Aa"一样,所以"BB"成为了"Aa"的下一个节点,二者组成了一个小型链表,但是"BB"的加入一样还是导致了++size,所以size变为3:
在这里插入图片描述
map.put(“2”, “6”)时,可以发现代码已经运行到了resize()方法,也就是扩容方法了,同时size也变成了4:在这里插入图片描述

最后运行结果如下:
在这里插入图片描述

总结

通过如上代码运行和debug的参考,可以得出HashMap里的size属性指的就是键值总数,因为哪怕新加的元素和旧元素hash值相等而equals结果不同,会处于同一链表中,size一样会加一,而size大小最终决定了是否要进行扩容。

  • 18
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 18
    评论
HashMap是Java中常用的数据结构之一,它基于哈希表实现。在JDK 1.8中,HashMap的底层实现主要包括数组和链表(或红黑树)两部分。 首先,HashMap内部维护了一个Entry数组,每个Entry对象包含了键值对的信息,包括键、值和向下一个Entry的针。数组长度是固定的,但可以根据需要进行扩容。 当我们向HashMap中插入一个键值对时,首先会根据键的hashCode()方法计算出一个哈希值。然后,通过哈希值与数组长度取模的方式确定该键值对在数组中的位置。如果该位置上已经存在其他键值对,就会发生冲突。 解决冲突的方法是使用链表或红黑树。在JDK 1.8中,当链表长度超过一定阈值(默认为8)时,链表会转换为红黑树,以提高查找效率。这样,在插入、删除和查找操作时,可以通过哈希值快速定位到对应的链表或红黑树,然后再在链表或红黑树中进行操作。 当我们需要查找一个键对应的值时,HashMap会根据键的哈希值找到对应的位置,然后遍历链表或红黑树来找到具体的键值对。 需要注意的是,HashMap并不保证元素的顺序,即插入和遍历的顺序不一定相同。如果需要有序的集合,可以考虑使用LinkedHashMap。 总结一下,JDK 1.8中HashMap的底层原理主要是通过数组和链表(或红黑树)来实现,通过哈希值快速定位到对应的位置,然后在链表或红黑树中进行操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值