超详细!ArrayList源码图文解析

本文详细解析ArrayList的源码,包括add、remove操作,以及扩容规则。重点讨论了add(E object)、add(int index, E object)、remove(int index)、remove(Object object)的方法实现,并揭示了ArrayListIterator的迭代器原理和使用时的注意事项,包括可能出现的异常情况及其原因。" 106681247,8388961,STM32F103 GPIO 库函数详解与应用,"['嵌入式开发', 'STM32', '微控制器', 'GPIO接口', 'C语言编程']
摘要由CSDN通过智能技术生成

不诗意的女程序媛不是好厨师~
转载请注明出处,From李诗雨—[https://blog.csdn.net/cjm2484836553/article/details/104329665]

昨天玩了很久的arraycopy,今天让我们来看看ArrayList的源码吧。

是的,又到了发挥我拙劣的画技的时候了~

先预览一下本篇文章的大纲:

在这里插入图片描述

下面我们就开始ArrayList的源码图解之旅吧,先从增删改查讲起,然后再讲ArrayListIterator的源码,当然这之间我们还会穿插讲一下几个大坑及注意事项~

1.增

ArrayList添加元素的操作,涉及到2个方法 add(E object)add(int index, E object)

1.1 add(E object) 直接在尾部添加一个元素

add(E object)这个方法,是直接添加一个元素,是在尾部进行插入。

如果原数组的大小不够会先进行扩容。

最终将数据添加在尾部,同时大小加1.

源码如下:
在这里插入图片描述

1.2 add(int index, E object) 在指定位置添加一个元素

add(int index, E object)这个函数是指在 index的位置 ,插入一个新元素。

  • 我们先看插入操作的核心步骤:

    从要插入的位置开始的所有数据,都要往先后挪一位;然后再把要插入的数据放进去。

    画了个图 方便大家理解:
    在这里插入图片描述

  • 了解了插入的核心步骤之后,我们就来看看 add(int index, E object)的源码中,插入一个元素到指定位置具体是怎么实现的吧。

    一、要先检测要插入的位置index是否合法。

    二、判断数组是否够用:

    a. 如果数组够用,即 s<a.length时,直接调用arraycopy(),将从index开始的所有数据都往后挪一位。(关于arraycopy的使用我上一篇已经详细讲过了,所以这里我们应该知道他是从后往前依次往后挪一位过去的)。

    b. 如果数组满了,即s>=a.length时,这里就要

    ​ (1)先将原数组进行扩容,生成新的数组;

    ​ (2)将原数组中index之前的数据复制到新数组对应的位置中去。

    ​ (3)将原数组中index之后的数据往后挪一位的移动到新的数组中去。

    ​ (4)将新数组赋给array。

    三、将要添加的元素放在index的位置,同时有效数据个数size+1。

    源代码见下图:
    在这里插入图片描述

补充:扩容规则

我们都知道,数组的大小是不可变的,而ArrayList的大小是可变的。而ArrayList底层也是用到了数组,那ArrayList是如何做到大小可以动态变化的呢?

答案就是通过扩容的方式。

也就是Object[] newArray = new Object[newCapacity(s)];这句代码。

现在我们来具体看看newCapacity(s)的实现:

在这里插入图片描述
在这里插入图片描述

这里我们做一下解释:

当目前的容量currentCapacity<6 时,increment=12;

否则的话 increment等于currentCapacity的一半。

最终返回的大小是 currentCapacity+increment

也就是说,扩容之后要么是在原有的基础上 +12,要么就是扩大为原来的1.5倍。

2.删

ArrayList的删除操作,我们也来看两个 remove(Object object)remove(int index)

2.1 remove(int index) 删除指定位置的元素

  • 同样,我们先来看看删除的核心操作:

    对应的代码就是System.arraycopy(a, index + 1, a, index, --s - index);这句代码,

    即 :如果要删除【index】位置的元素,那就要把【index】之后的所有元素都往前挪一位,覆盖掉index原本的位置.

    同样来画个图来帮助大家理解:
    在这里插入图片描述

  • 了解了核心的操作之后,我们就来看看 remove(int index) 的源代码吧:
    在这里插入图片描述

2.2 remove(Object object) 删除某个已知元素

remove(Object object) 删除某个已知元素。

上面我们已经知道了删除指定位置元素的操作,那如果要删除某个已知元素的话,我们是不是也应该先找到它对应的位置,然后再进行删除呢。

  • 那问题来了,怎么找到元素对应的位置呢?

    对,通过循环遍历,并进行比较 找到对应的index.
    在这里插入图片描述

▲有个坑!

▲【注意】:

调用remove方法, 会, 且只会 删除第一个与传入对象通过equals方法判断相等的元素。

如果传入null, 则删除掉第一个null元素。

所以, 如果自定义类想要使用remove方法从列表删除某个指定值对象, 还需要实现该类型自己的equals方法才行!

▲还有个坑!

ArrayList是可以顺序删除节点的,但是!如果使用普通for循环,必须是从后往前删。不能从前往后删。

我们先来看一下【错误示范】:

ArrayList list
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值