Java ArrayList源码学习(学习记录,可能有很多理解不对的地方,大佬勿喷,谢谢)
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
/*
*是当对象序列化的时候对象的一个标识,作用是序列化时转化为byte流,还能反序列化成原始类,主要用于版本控制
*/
private static final long serialVersionUID =8683452581122892189L;
/*
* 默认初始容量为10
*/
private static final int DEFAULT_CAPACITY = 10;
/*
* 空数组,在调用无参构造方法时默认是这个空数组
*/
private static final Object[] EMPTY_ELEMENTDATA = {};
/*
* 用于保存数据的数组
*/
private trainsient Object[] elementData;、
/*
* 元素的数量
*/
private int size;
/*
* 通过构造方法传入默认容量设置数组大小
*/
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) { //大于0新生成一个容量为传入参数的数组
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) { //等于0时生成空数组
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
/*
* 默认生成空的数组
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
/*
* 把传入的集合中的值复制到arryList里
*/
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray(); //c转为数组后传递给arayList
if ((size = elementData.length) != 0) { //如果长度不等于0
if (elementData.getClass() != Object[].class) //如果两者的类型不一致
elementData = Arrays.copyOf(elementData, size, Object[].class); //把传入的数组赋给arrayList数组
} else { //如果长度等于0,生成空数组
this.elementData = EMPTY_ELEMENTDATA;
}
}
/*
* 实际尺寸
*/
public void trimToSize() {
modCount++; ///定义于ArrayList的父类AbstractList,用于存储结构修改次数
if (size < elementData.length) { // 如果arrayList长度小于数组长度
elementData = (size == 0) //数据数组长度是否为0?空数组:复制数组数据和长度
? EMPTY_ELEMENTDATA
: Arrays.copyOf(elementData, size);
}
}
/*
* 确保容量容纳得下数据
*/
public void ensureCapacity(int minCapacity) { //所需最小的容量
int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
? 0 : DEFAULT_CAPACITY; //如果 arrayList数据不为空数组?0 :默认值10
if (minCapacity > minExpand)
ensureExplicitCapacity(minCapacity);
}
}
/*
* 计算容量
*/
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { //如果为空
return Math.max(DEFAULT_CAPACITY, minCapacity); //返回默认容量和最小容量比较大那个
}
return minCapacity;
}
/*
* 确保装得下
*/
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++; //动态增长时的数
if (minCapacity - elementData.length > 0) 如果最小容量比arrayList的容量大
grow(minCapacity); //增长minCapacity
}
/*
* 数组扩充容量
*/
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length; //获取数组长度
int newCapacity = oldCapacity + (oldCapacity >> 1);//新容量为旧容量的1.5倍
if (newCapacity - minCapacity < 0) //如果新容量小于传入的容量
newCapacity = minCapacity; //新容量等于传入容量
if (newCapacity - MAX_ARRAY_SIZE > 0) //如果新容量超过最大值
newCapacity = hugeCapacity(minCapacity); //判断值是否大于最大容量
elementData = Arrays.copyOf(elementData, newCapacity); //把元素和新容量赋给arrayList
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0)
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ? //最小容量是否超过最大容量?integer最大值:integer最大值-8
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
/*
* 最大的数组容量,在jvm中获取数组长度使用了arraylength字节码指令,
* 长度8是用来记录字节码指令的,并不固定是8,为了减少内存溢出(OOM)
*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
/*
* 长度
*/
public int size() {
return size;
}
/*
* 是否为空
*/
public boolean isEmpty() {
return size == 0;
}
/*
* 是否包含某个元素
*/
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
/*
* 获得元素索引
*/
public int indexOf(Object o) {
if (o == null) { //如果为null,遍历数组,查询为null的下标,找到返回下标
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else { //如果元素不为null,遍历,如果找到返回下标
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1; //没找到返回-1
}
/*
* 获得最后一个元素的索引
*/
public int lastIndexOf(Object o) { //逻辑同上,只是把数组从后往前遍历
if (o == null) {
for (int i = size-1; i >= 0; i--)
if (elementData[i]==null)
return i;
} else {
for (int i = size-1; i >= 0; i--)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
/*
* 复制,返回数组实体,无值
*/
public Object clone() {
try {
ArrayList<?> v = (ArrayList<?>) super.clone();
v.elementData = Arrays.copyOf(elementData, size);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError(e);
}
}
/*
* 调用arrays的数组方法
*/
public Object[] toArray() {
return Arrays.copyOf(elementData, size);
}
/*
* 如果列表适合指定数组,返回它,否则,创建一个新数组,分配
*指定数组的运行时类型和大小
*/
public <T> T[] toArray(T[] a) {
if (a.length < size)
return (T[]) Arrays.copyOf(elementData, size, a.getClass());
System.arraycopy(elementData, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}
/*
* 根据索引获得元素值
*/
E elementData(int index) {
return (E) elementData[index];
}
/*
* 检查索引范围,返回元素值
*/
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
/*
* 替换值
*/
public E set(int index, E element) {
rangeCheck(index); //检查范围
E oldValue = elementData(index); //把索引为index的值得到
elementData[index] = element; //把元素设置到该位置
return oldValue;
}
/*
* 添加element
*/
public boolean add(E e) {
ensureCapacityInternal(size + 1); //扩充长度
elementData[size++] = e; //插入在末尾
return true;
}
/*
* 根据索引添加element
*/
public void add(int index, E element) {
rangeCheckForAdd(index); //检查是否在范围内
ensureCapacityInternal(size + 1); //扩充
System.arraycopy(elementData, index, elementData, index + 1,
size - index); //复制指定的源数组的数组,把elementData中从index开始以后的元素复制到elementData的index+1的位置上,个数为size-index个
elementData[index] = element; //将elementData下边index位置赋值目标值
size++; //arrayList+1
}
/*
* 根据索引删除element
*/
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index); //得到索引index的元素
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved); //把elementData中,index后的元素复制到数组中
elementData[--size] = null;
return oldValue;
}
/*
* 删除元素,同 add
*/
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
/*
* 删除元素
*/
private void fastRemove(int index) {
modCount++;
int numMoved = size - index - 1; //得到删除元素后的个数
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved); //把删除元素之后的元素复制到数组中
elementData[--size] = null; // 数组前移一位,size自减,空出来的位置置null,具体的对象的销毁由Junk收集器负责
}
public void clear() {
modCount++;
for (int i = 0; i < size; i++)
elementData[i] = null; 清空数组,设置长度为0
size = 0;
}
/*
* 把集合添加进arrayList
*/
public boolean addAll(Collection<? extends E> c) {
Object[] a = c.toArray(); //把C变成数组
int numNew = a.length; //获取数组长度
ensureCapacityInternal(size + numNew); //增加操作数
System.arraycopy(a, 0, elementData, size, numNew); //把新的数组复制到elementData中
size += numNew; //更改elementData长度
return numNew != 0;
}
/*
* 在指定的索引后添加集合
*/
public boolean addAll(int index, Collection<? extends E> c) {
rangeCheckForAdd(index);
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); /
int numMoved = size - index; //需要位移的元素个数
if (numMoved > 0)
System.arraycopy(elementData, index, elementData, index + numNew,
numMoved); //把元素放到移动后的位置
System.arraycopy(a, 0, elementData, index, numNew); //把集合放入elementData中
size += numNew;
return numNew != 0;
}
/*
* 删除索引之间的元素
*/
protected void removeRange(int fromIndex, int toIndex) {
modCount++;
int numMoved = size - toIndex; //需要移动的元素是删除元素后的元素
System.arraycopy(elementData, toIndex, elementData, fromIndex,
numMoved); 将elementData从toIndex位置开始的元素向前移动到fromIndex
// clear to let GC do its work
int newSize = size - (toIndex-fromIndex);
for (int i = newSize; i < size; i++) {
elementData[i] = null; //把toIndex后的元素置空
}
size = newSize;
}
private void rangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private void rangeCheckForAdd(int index) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private String outOfBoundsMsg(int index) {
return "Index: "+index+", Size: "+size;
}
/*
* 删除集合
*/
public boolean removeAll(Collection<?> c) {
Objects.requireNonNull(c); //判断c是否为空
return batchRemove(c, false);
}
/*
* 保留集合
*/
public boolean retainAll(Collection<?> c) {
Objects.requireNonNull(c);
return batchRemove(c, true);
}
private boolean batchRemove(Collection<?> c, boolean complement) {
final Object[] elementData = this.elementData;
int r = 0, w = 0; //w为write,r为read
boolean modified = false;
try {
for (; r < size; r++)
if (c.contains(elementData[r]) == complement) ; //若保留,就将相同元素移动到前段,不删除,就将不同元素移动到前段
elementData[w++] = elementData[r]; //将原数组的r位置的数据覆盖掉w位置的数据,r位置的数据不变,并其w自增,r自增。
} finally {
if (r != size) { //确保异常抛出前的部分可以完成期望的操作,未遍历的部分会接到后面
System.arraycopy(elementData, r,
elementData, w,
size - r);
w += size - r;
}
if (w != size) { //如果w == size ,表示全部元素被保留,那么没有删除操作,所以返回false,反之,返回true,没有删除操作。当w != size的时候,即使抛出异常,也能正确处理抛出前的操作,所以w始终为保存的前段部分
for (int i = w; i < size; i++)
elementData[i] = null;
modCount += size - w;
size = w; //新的大小为保留元素个数
modified = true;
}
}
return modified;
}
}
网友评论