【java集合体系中各集合的扩容机制】


前言

在之前提到多数据存储的三种方式:数组、链表、树,它们单独使用时都非常不方便,因此存在一些集合接口提高了多数据存储的能力。
集合分为单列集合和双列集合,其下的一些实现类都存在自己的扩容机制,本篇介绍其扩容机制

一、单列集合List

1.1 ArrayList

由jdk1.8 底层源码可知,默认情况下加载因子是1,且默认容量为10,存在自动扩容机制

  • 默认加载因子:当元素个数超过 容量长度*加载因子的系数时,进行扩容。
    即ArrayList中,元素个数>原长度的一倍(即原长度),就进行扩容
    在这里插入图片描述
  • 通过ArrayList中的grow()方法及其他方法进行自动扩容的操作
    且不同jdk版本中grow()位置可能不一样

  • 存在的问题:
    • ArrayList其实长度有局限,如果超出长度的情况下,需要内部进行扩容操作,只要是扩容,就会出现垃圾空间
    • 通过无参构造创建集合,第一次存值的时候就要进行扩容操作,意味着垃圾空间的产生
    • 扩容的基本量是原始的1/2,然后把之前的数据拷贝到新建的数组中去

  • 因此在ArrayList进行定义时,如果暂时不使用,就定义长度为0;如果立马进行添加操作,要添加几个就定义多少长度
    进行一个预估长度,避免出现ArrayList进行自动扩容时产生多余的垃圾空间

1.2 Vector

由jdk1.8 底层源码可知,默认容量为10,存在自动扩容机制
在这里插入图片描述
在这里插入图片描述

  • Vector默认情况下加载因子是1,扩容后的容量是之前的2倍(未设置容量增量时),超过即自动扩容

  • Vector扩容时可以不用默认扩容的容量,即可以设置容量增量,而ArrayList不可以

1.3 Stack

Stack栈继承自Vector。添加了同步的push(E e),pop(),peek(),search()方法,默认容量和扩容机制同Vector

  • Stack默认容量是10,加载因子: 1

  • Stack扩容机制: 如果用户没有指定扩容步长,按原数组长度的2倍扩容,否则按用户指定的扩容步长扩容。
    如果扩容后的大小小于实际需要的大小,将数组扩大到实际需要的大小

1.3 LinkedList

没有扩容机制,因为其底层是双向链表结构。不存在数组的扩容一说,没有初始化大小,也没有扩容的机制,就是一直在前面或者后面新增就好。

二、单列集合Set

2.1 HashSet

由jdk1.8 底层源码可知,默认加载因子为0.75,用来判断扩容的时机,因此存在自动扩容机制
在这里插入图片描述

  • 默认容量16,加载因子0.75,超出后按照1倍扩容

2.2 LinkedHashSet

在这里插入图片描述

  • 默认容量16,加载因子0.75,超出后按照2倍扩容

2.3 TreeSet

  • 由源代码可知,创建TreeSet对象时是构造一个空树集,底层原理是红黑树,因此不存在扩容机制

在这里插入图片描述

三、双列集合Map

3.1 HashMap

jdk1.8默认初始容量0,当第一次put元素的时候才扩容为16,jdk1.7是初始化容量为16,即默认容量16,加载因子0.75,超出后按照1倍扩容(最大容量为1<< 30)

  • map如果只提供初始空间大小,每次扩充的值为默认的75%
    如果提供扩充阈值,则按照该阈值扩充
    在这里插入图片描述

3.2 Hashtable

扩容加载因子(0.75),当超出默认长度(int)(11*0.75)=8时,扩容为oldx2+1。新容量为原容量的2倍+1.
在这里插入图片描述

3.3 LinkedHashMap

LinkedHashMap的扩容机制 LinkedHashMap的扩容机制与HashMap类似。

  • 当LinkedHashMap的元素数量超过负载因子(默认为0.75)与容量的乘积时,会触发扩容操作。 扩容操作会将容量扩大为原来的两倍,并重新计算每个元素在新容量下的位置。
  • 在扩容过程中,原来的元素顺序会被保留,因为LinkedHashMap是基于链表和哈希表实现的

3.4 TreeMap

当存储在Treemap中的元素数量达到当前容量的75%时,Treemap会自动进行扩容操作。

  • 进行扩容时,Treemap会创建一个新的红黑树,新树的容量是原来树容量的两倍。
  • 将原树中的所有元素按照它们的key值重新插入到新树中。
    由于红黑树的插入操作的时间复杂度是O (logN),这个过程会有一定的时间代价。
  • 扩容后,原来的红黑树会被回收释放空间
  • 11
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值