Java基础 | 14.HashMap新增结点机制、数组扩容机制、链表树化机制

1.HashMap总述

  • 无序,线程不安全,效率高;
  • 底层结构为数组 + 链表(+ 红黑树)

image-20220401144430293

image-20220401140214288

2.新增结点机制

  • 确定数组下标时会对key调用Object.hashCode( ),因此自定义类需要重写hashCode( );
  • 确定key是否相等时会对key调用Object.equals( ),因此自定义类需要重写equals( );
  • 结点判断相等时,会替换结点中的value。

绘图1202203311915

3.数组扩容机制

  • 扩容调用底层的resize( )实现,将数组容量扩为2倍

  • 无参构造时,默认的数组容量为16;

  • 遇到以下任意一种情况时,便会对数组进行扩容:

    – 插入新结点后满足 总结点数 >(数组容量 * 0.75)时,默认的首次扩容时机为:插入第13(16 * 0.75 + 1)个结点之前

    – 插入新结点后 链表长度 > 8 但尝试树化失败(长度 > 8,但不满足数组长度>=64)时。

  • 扩容时,创建新的容量为2倍的数组,然后将原数组中的元素重新hash,分配到新数组中。也正是因为扩容流程繁琐,因此建议在创建HashMap对象时使用有参构造减少扩容

注意:重新hash是指:为结点重新分配数组下标:

元素的下标是通过key的hash值与数组容量计算出来的,数组扩容改变了数组容量,因此结点有可能会获得全新的数组下标。

4.链表树化机制(JDK1.8)

  • JDK1.8之后会在满足一定条件时树化链表:调用底层的treefyBin( )实现,将链表转换成红黑树

  • 插入新结点后链表长度 > 8 就会尝试树化:

    – 数组长度 < 64,拒绝树化,转而调用resize( )扩容数组;

    – 数组长度 >= 64,树化链表;

  • 当执行某操作导致红黑树结点数 < 6,红黑树便会退化成链表。

注意:导致红黑树结点数下降有以下两种可能

  • 使用remove( )删除结点后;
  • 数组扩容导致重新Hash
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值