【集合】ArrayList

ArrayList源码解析
本文深入分析ArrayList源码,探讨其动态扩容机制、时间复杂度及集合操作。了解ArrayList如何高效管理数组,掌握插入、删除、查询元素的性能特点。

主要对源码中几个常用的方法进行分析。ArrayList是基于数组实现的,当我们添加元素的时候,他可以替我们动态的为数组扩容。

1.源码

1.1属性

    /**
     * 默认初始容量。
     */
    private static final int DEFAULT_CAPACITY = 10;
    /**
     * 当声明arrayList的时候,长度指定为0,就会使用这个数组
     */
    private static final Object[] EMPTY_ELEMENTDATA = {};
    /**
     * 当new ArrayList();的时候就会把这个null元素的数组的引用给elementData,
     */
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
    /**
     * 实际存储元素的数组
     */
    transient Object[] elementData; // non-private to simplify nested class access
    /**
     * 这个是元素的个数
     */
    private int size;

elementData使用transient来修饰,表示这个数组不参与序列化。

1.2 构造方法ArrayList()

当实例化一个对象的时候,刚开始会使用DEFAULTCAPACITY_EMPTY_ELEMENTDATA 这个没有元素的数组。
在这里插入图片描述

1.3 构造方法ArrayList(int initialCapacity)

当initialCapacity大于0的时候,就会直接new 一个Object数组给elementData,可以看出来,ArrayList实际上是使用elementData来储存元素的。
在这里插入图片描述

1.4 添加元素方法add(E)

添加元素方法中主要有一个检查是否需要扩容的方法ensureCapacityInternal(int)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
add()方法:当容量不够用的时候就会进行自动扩容,扩容为原来的1.5倍。

1.5 删除元素方法remove(int)

在这里插入图片描述
可以看出删除方法的返回值是元素本身,而且并没有缩小容量

1.6 获取元素get(int)

在这里插入图片描述
在这里插入图片描述
首先检查坐标是否合法,然后按照下标返回元素

2.总结

简单的看一下源码,其中有一个变量modCount,这个是AbstractList中的元素,主要的作用就是有用来表示对list操作了多少次。这个可能是为了list做线程同步做准备。

2.1 ArrayList是怎么扩容的?

通过看源码,可以知道,添加元素的时候首先检查是否需要扩容,当容量不够用的时候,就使用grow(int minCapacity)方法来进行扩容,新建一个容量为原来的1.5倍的新数组,然后将原来的数组元素通过Arrays.copyOf()这个方法复制到新的数组中。

2.2 ArrayList插入、删除、查询元素的时间复杂度各是多少?

add(E):直接将元素反正最后不为空的位置,复杂度O(1);
remove(int):直接根据元素下标删除,然后将后面的元素向前移动一位,使用了System.arraycopy,复杂度O(n);
get(int):直接根据下标获取,复杂度O(1);

2.3 怎么求两个集合的并集、交集?

并集使用addAll(Collection)
在这里插入图片描述
交集使用retainAll(Collection<?> c)
在这里插入图片描述
在这里插入图片描述

还有什么下次在补充吧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值