前言
本篇文章先回顾一下ArrayList有关特点和常用API,然后介绍重点——ArrayList源码分析
ArrayList相关
(关于集合的详细内容,可以参见:java集合 ,本文只介绍ArrayList)
1.介绍
(1)特点
ArrayList 类实现一个可增长的动态数组,位于 java.util.ArrayList
。实现了 List 接口,它可以存储不同类型的对象(包括 null 在内),而数组则只能存放特定数据类型的值。
存储类型只能存储引用数据类型,如果是基本数据类型,需要用到他们的包装类
(关于基本类型和引用类型区别,可参见:http://t.csdn.cn/xCg4M)
(2)定义格式
import java.util.ArrayList; // 引入 ArrayList 类
ArrayList<E> objectName =new ArrayList<>(); // 初始化
E: 泛型数据类型,用于设置 objectName 的数据类型,只能为引用数据类型。 objectName: 对象名。
2.常用方法(API)
增删查改
方法名 | 说明 |
---|---|
public boolean add(要添加的元素) | 将指定的元素追加到此集合的末尾 |
public boolean remove(要删除的元素) | 删除指定元素,返回值表示是否删除成功 |
public E remove(int index) | 删除指定索引处的元素,返回被删除的元素 |
public E set(int index,E element) | 修改指定索引处的元素,返回被修改的元素 |
public E get(int index) | 返回指定索引处的元素 |
public int size() | 返回集合中的元素的个数 |
3.遍历
基本介绍可参考 Collection的三种遍历方式
(1)Iterator
(2)增强for循环
ArrayList源码分析
1.底层原理
(1)利用空参创建的集合,在底层创建一个默认长度为0的数组
(2)添加第一个元素时,底层会创建一个新的长度为10的数组
(3)存满时,会扩容1.5倍
(4)如果一次添加多个元素,1.5倍还放不下,则新创建数组的长度以实际为准
总之,ArrayList底层还是以数组形式存储,至于扩容的细节,可以参考源码
2.源码分析
(以Java17为例)
先介绍源码中的几个常量
// 默认的初始容量(注意添加第一个元素时才会用上)
private static final int DEFAULT_CAPACITY = 10;
//Shared empty array instance used for empty instances.
private static final Object[] EMPTY_ELEMENTDATA = {
};
// 一个空数组,用来赋值给刚创建的elementData
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {
};
// ArrayList 的底层数组
transient Object[] elementData;
// ArrayList的元素个数
private int size;
首先从空参构造函数入手
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
DEFAULTCAPACITY_EMPTY_ELEMENTDATA
被定义为空数组,即空参创建的集合,在底层创建了一个默认长度为0的数组
接下来添加方法add涉及的源码比较多,而且往往还是一层套一层,所以直接把几个关键代码贴在一起。分两种情况讨论——空集合&元素个数为10的集合
(1)空集合添加第一个元素
(2)已经有10个元素再继续添加
参考链接:
https://www.bilibili.com/video/BV17F411T7Aop=190&vd_source=752a4cd440b20a1953dc8d254ef99696