ArrayList的底层实现原理(JDK8)

ArrayList的底层是通过数组实现的。

一、知识点回顾

数组特点:

  • 存储区间是连续的,且占用内存严重,空间复杂度很大,时间复杂度为 O(1)。
  • 优点: 随机读取效率很高,原因是数组是连续的(随机访问性强,查找速度快)。
  • 缺点: 插入和删除效率低,因插入数据,这个位置后面的数据要在内存中后移,且大小固定,不易动态扩展。

在这里插入图片描述

二、ArrayList 的 add() 和 remove() 的实现

2.1 list.add(e) 实现原理

  • 第 1 步,首先判断当前size+1,是否超出数组的最小容量10:
    • 如果没有超出最小容量10,则将10作为所需的最小容量;
    • 如果超出最小容量10,则将size+1作为最需的最小容量。
  • 第 2 步,判断所需最小容量是否大于数组的实际容量(length):
    • 如果所需最小容量 > 数组的实际容量,则需要扩容
      • 调用 grow() 方法,判断所需的最小容量是否超过实际容量的3/2(向上取整,length = length + length >> 1):
        • 如果所需最小容量 > 实际容量的3/2,则采用所需最小容量作为新容量;
        • 如果所需最小容量 ≤ 实际容量的3/2,则采用实际容量的3/2作为新容量。
      • 判断新容量是否超出 Integer.MAX_VALUE - 8:
        • 如果新容量 > Integer.MAX_VALUE - 8,根据所需最小容量重新计算;
          • 判断所需最小容量是否小于0:
            • 如果所需最小容量 < 0,则抛出内存溢出异常:OutOfMemoryError
          • 判断所需最小容量是否超出 Integer.MAX_VALUE - 8:
            • 如果所需最小容量 > Integer.MAX_VALUE - 8,则采用 Integer.MAX_VALUE 作为新容量;
            • 如果所需最小容量 ≤ Integer.MAX_VALUE - 8,则采用 Integer.MAX_VALUE - 8 作为新容量。
      • 将数组按照新容量扩容:elementData = Arrays.copyOf(旧数组, 新容量),按照新容量创建一个新数组,然后将之前的数组内容复制到新数组中。
    • 如果所需最小容量 ≤ 数组的实际容量,则不需要扩容
  • 第 3 步,将新增的值赋值到 elemetnData[size] 上,然后size扩容1。

在这里插入图片描述

2.2 list.remove() 实现原理

  • 第1步,检查索引范围,判断索引是否大于等于容量大小(size):
    • 如果索引 ≥ 容量大小,抛出索引越界异常:IndexOutOfBoundsException
  • 第 2 步,获取索引位置上的元素值;
  • 第 3 步,将数组上索引位置以后的元素向前复制 1 位;
  • 第 4 步,将数组末位位置值置为null,方便 GC 进行垃圾回收;
  • 第 5 步,将之前获取索引位置上的元素值进行返回。

在这里插入图片描述

整理完毕,完结撒花~ 🌻

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不愿放下技术的小赵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值