ArrayList 是一个数组队列,相当于 动态数组。与Java中的数组相比,它的容量能动态增长。它继承于AbstractList,实现了List, RandomAccess, Cloneable, java.io.Serializable这些接口。
ArrayList属性
private static final long serialVersionUID = 8683452581122892189L;
这个叫做序列化id,若有兴趣理解可参考这位大佬的见解:java 序列化ID的作用_ostracod_lvj的博客-CSDN博客_序列化id有什么用
// 默认初始的容量
private static final int DEFAULT_CAPACITY = 10;
// 定义一个空的数组实例以供其他需要用到空数组的地方调用
private static final Object[] EMPTY_ELEMENTDATA = {};
// 定义一个空数组,跟前面的区别就是这个空数组是用来判断ArrayList第一添加数据的时候要扩容多少。默认的构造器情况下返回这个空数组
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
// 当前数据对象存放地方,当前对象不参与序列化,数据存的地方它的容量就是这个数组的长度,同时只要是使用默认构造器(DEFAULTCAPACITY_EMPTY_ELEMENTDATA )第一次添加数据的时候容量扩容为DEFAULT_CAPACITY = 10
transient Object[] elementData; // non-private to simplify nested class access
// 数组列表的大小(它包含的元素的数量)
private int size;
// 要分配的数组的最大大小
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
//Integer.MAX_VALUE:一个常量,容纳int类型的最大值231-1
ArrayList构造方法
- 无参构造
// 构造一个初始容量为10的空列表
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
- int类型的有参构造
// 构造一个具有指定初始容量的空列表。
// 参数:initialCapacity—列表的初始容量
// 抛出:IllegalArgumentException -如果指定的初始容量为负值
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
- Collection对象的有参构造
// 构造一个包含指定集合元素的列表,按照集合的迭代器返回元素的顺序排列。
// 参数:c -将其元素放入列表中的集合
// 抛出:
// NullPointerException -如果指定的集合为空
// NullPointerException -如果指定的集合为空
public ArrayList(Collection extends E> c) {
Object[] a = c.toArray();
if ((size = a.length) != 0) {
if (c.getClass() == ArrayList.class) {
elementData = a;
} else {
elementData = Arrays.copyOf(a, size, Object[].class);
}
} else {
// replace with empty array.
elementData = EMPTY_ELEMENTDATA;
}
}
ArrayList其他方法
因为在所有添加数据的操作上面都要需要判断当前数组容量是否足以容纳新的数据
所以在总结这个前必须先了解一个机制:ArrayList扩容机制(相关扩容方法)
能力有限在此参考文章:
jdk1.8ArrayList主要方法和扩容机制(源码解析)_青元子的博客-CSDN博客_arraylist的扩容机制
ArrayList扩容详解_架构师忠哥的博客-CSDN博客_arraylist扩容
-
扩容方法(以下是我参考上述文章的个人理解,如果理解有遇到困难可去参考上述引用文章的详细内容)
// 判断当前数组是否是默认构造方法生成的空数组,如果是的话minCapacity=10反之则根据原来的值传入下一个方法去完成下一步的扩容判断 public void ensureCapacity(int minCapacity) { int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) // any size if not default element table ? 0 // larger than default for default empty table. It's already // supposed to be at default size. : DEFAULT_CAPACITY; if (minCapacity > minExpand) { ensureExplicitCapacity(minCapacity); } } // minCapacity表示修改后的数组容量,minCapacity = size + 1 private static int calculateCapacity(Object[] elementData, int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { return Math.max(DEFAULT_CAPACITY, minCapacity); } return minCapacity; //可以看到如果是使用了空数组EMPTY_ELEMENTDATA话,那么不会返回默认的初始容量 } //判断看看是否需要扩容 private void ensureCapacityInternal(int minCapacity) { ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); } //判断当前ArrayList是否需要进行扩容 private void ensureExplicitCapacity(int minCapacity) { //快速报错机制(详细内容参考第一篇引用文章) modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); } // ArrayList扩容的核心方法,此方法用来决定扩容量 // 增加容量以确保它至少可以容纳最小容量参数指定的元素数量 // 参数: minCapacity - 所需的最小容量 private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); } private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }
目前理解遇阻,晚点补充



