<Java学习笔记>HashMap底层原理浅谈

HashMap的底层以数组+单向链表/红黑树存储。数组一个位置可以存在多对数据,这些数据以链表或红黑树的形式存储。加入红黑树的存储方式是在JDK8.0。

创建数组时,其初始化长度为16(JDK7.0和JDK8.0初始化数组的时机不同)。添加数据时,首先调用数据的key所属类的hashCode()方法计算出哈希值,哈希值经一定的变换求得该数据在数组的位置。

得到数据在数组中的位置后,进入以下一系列的判定:

  • 若该位置为空,不存在任何数据。
    • 直接添加数据。
  • 若该位置已存在一个或多个元素,进入下一个判定:
    • 对该位置已存在的元素的key值进行遍历
      • 所有元素key的哈希值与欲添加的数据key的哈希值不同
        • 添加数据到链表的末尾(Java8及以后)。
        • 添加数据到链表的开头(Java7及以前)。
      • 存在某些元素key的哈希值与欲添加数据key的哈希值相同,此时,调用equals()方法,进入下一个判断:
        • 哈希值相同,但equals()都返回false
          • 添加数据到链表的末尾(Java8及以后)。
          • 添加数据到链表的开头(Java7及以前)。
        • 哈希值相同,并且存在equals()返回true的情况
          • 判断欲添加的数据的key值在集合中已存在,不予添加。

HashMap存在填充因子、扩容临界值等属性。扩容临界值=数组容量*填充因子。当数组中不为空的位置个数大于扩容临界值时,进行扩容操作。(并不是数组满了才扩容)

扩容操作:创建新的数组,长度为旧数组的2倍,将原来的元素复制过来。

在JDK8.0中,当链表过长,且数组容量达到一定标准时,索引位置上的数据将转换成以红黑树的形式存储,提高了遍历的效率。

注:以上笔记是笔者自己的理解,并非标准定义,如有错误,欢迎指出,不甚感激!

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值