本文共 3023 字,大约阅读时间需要 10 分钟。
好久没写博客,一直是写在笔记上面。
我一直用的JDK8,所以今天的源码分析也是基于JDK8。
ArrayList 是一个动态数组队列。与Java中的数组相比,它的容量能动态增长。它继承于AbstractList,实现了List, RandomAccess, Cloneable, java.io.Serializable这些接口。
ArrayList 的爸爸是AbstractList,实现了List。AbstractList 提供了相关的添加、删除、修改、遍历等功能。 ArrayList 实现了RandmoAccess接口,支持快速随机访问。 ArrayList 实现了Cloneable接口,即覆盖了函数clone(),能被克隆。 ArrayList 实现java.io.Serializable接口,这意味着ArrayList支持序列化,能通过序列化去传输。
和Vector不同,ArrayList中的操作不是线程安全的!所以,建议在单线程中才使用ArrayList,而在多线程中可以选择Vector或者CopyOnWriteArrayList。
数组长度
.........
public class ArrayListextends AbstractList implements List , RandomAccess, Cloneable, Serializable { // 序列化id private static final long serialVersionUID = 8683452581122892189L; // 初始的容量(这里和Android Java不一样,Android是12) private static final int DEFAULT_CAPACITY = 10; // 一个空对象 private static final Object[] EMPTY_ELEMENTDATA = new Object[0]; // 一个空对象,如果使用默认构造函数创建,则默认对象内容默认是该值 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = new Object[0]; // 当前数据对象存放地方,当前对象不参与序列化 transient Object[] elementData; // 当前数组长度 private int size; // 数组最大长度 private static final int MAX_ARRAY_SIZE = 2147483639; }
public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; }//当进行第一次add的时候,elementData将会变成默认的增量长度:10.
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); } }
public ArrayList(Collection c) { //将collection对象转换成数组,然后将数组的地址的赋给elementData。 elementData = c.toArray(); //如果它的长度不为0,进而判断它是否为Object类型的数组,如果不是的话,给它copyOf()为一个Object类型的数组。否则,给它置空。 if ((size = elementData.length) != 0) { if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class); } else { // replace with empty array. this.elementData = EMPTY_ELEMENTDATA; } }
add方法:
在指定位置添加元素:首先rangeCheckForAdd(index)判断索引是否超出数组下标,之后检测是否需要扩容,使用System.arraycopy 将需要插入的位置(index)后面的元素统统往后移动一位。将新的数据内容存放到数组的指定位置(index)上。
索引没有越界时,操作数++,将指定位置(index)上的元素都往前移动一位,将最后面的一个元素置空,好让垃圾回收器回收,并且将原来的值oldValue返回
循环遍历所有对象,得到对象所在索引位置,然后调用fastRemove方法,执行remove操作
转载地址:http://vinwi.baihongyu.com/