注释arrayList源码的增删改查

  ArrayList这个类是顺序线性数据结构,是用数组实现,Object[]数组实现,增删改查全部是操作数组。查询时定位到特定元素比较快,插入和删除的话,要操作整个数组,消费性能高一些,而且是线程不安全的。只是对部分的源码进行了注释,如果哪里描述有误的话,欢迎指正!

 
 

public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
private static final long serialVersionUID = 8683452581122892189L;


/**
* Default initial capacity.
*/
private static final int DEFAULT_CAPACITY = 10; // 默认数组长度


/**
* Shared empty array instance used for empty instances.
*/
private static final Object[] EMPTY_ELEMENTDATA = {}; // 空实例


/**
* Shared empty array instance used for default sized empty instances. We
* distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
* first element is added.
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; // 默认空实例


/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer. Any
* empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
* will be expanded to DEFAULT_CAPACITY when the first element is added.
*/
transient Object[] elementData; // non-private to simplify nested class access
// transient 序列化时候,不打印这个字段的值,可以用jsonobject(fastjson.jar包)测试
/**
* The size of the ArrayList (the number of elements it contains).
*
* @serial
*/
private int size; // 数组长度
 
public ArrayList(int initialCapacity) {// 有参构造器:定义初始长度
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];// 实例化elementData
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;// 将定义好的空数组赋予elementData
} else {
throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity);// 抛出非法字符异常
}
}

 
public ArrayList() {// 无参构造器
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;// 将定义好的默认空数组赋予elementData
}


 
public ArrayList(Collection<? extends E> c) {// 有参构造器:集合
elementData = c.toArray();// 将collection对象转化为数组,Collection的toArray()方法返回的Object[],是不能被强制转换为子元素类型的
if ((size = elementData.length) != 0) {// 数组长度不等于0
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)// 判断c.toArray.返回值是不是Object[]
elementData = Arrays.copyOf(elementData, size, Object[].class);// 拷贝这个不是Object数组的值为Object数组
} else {
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;// 将定义好的空数组赋予elementData
}
}


public void trimToSize() {
modCount++;
if (size < elementData.length) {
elementData = (size == 0) ? EMPTY_ELEMENTDATA : Arrays.copyOf(elementData, size);// size长度不是0,重新为elementData赋值,长度为size;为0,将定义好的空数组赋予elementData
}
}

 
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);
}
}


private void ensureCapacityInternal(int minCapacity) {//扩容
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {// 空值
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);// 选择两者中的最大值
}


ensureExplicitCapacity(minCapacity);//扩容
}


private void ensureExplicitCapacity(int minCapacity) {
modCount++;


// overflow-conscious code
if (minCapacity - elementData.length > 0)// 目前最小容量小于数组长度
grow(minCapacity);// 扩容
}


 
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;//数组最大长度


 
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);// 抛出异常,或者长度等于int的最大值
// 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 溢出,超出int的最大值,变成了负数
throw new OutOfMemoryError();// 抛出内存溢出错误
return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;//如果长度大于最大值,返回int的最大值
}

 
public int size() {
return size;//返回数组长度
}


 
public boolean isEmpty() {
return size == 0;//判断是否空
}


 
public boolean contains(Object o) {
return indexOf(o) >= 0;//如果indexof返回值不小于0,包含此元素
}


 
public int indexOf(Object o) {//与o对象相同的第一个元素的下标
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i] == null)//遍历如果数组有null元素,证明有相同元素,返回
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))//遍历如果数组有和对象o相同的元素 ,返回
return i;
}
return -1;
}

 
public int lastIndexOf(Object o) {// 与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 E get(int index) {
rangeCheck(index);// 检查index是否正确,错误抛出异常
return elementData(index);
}

 
public E set(int index, E element) {// 为某个点赋值
rangeCheck(index);// 检查index是否正确,错误抛出异常


E oldValue = elementData(index);// 获取这个点原有值
elementData[index] = element;// 覆盖
return oldValue;
}


 
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;// 先赋值size再加1
return true;
}


 
public void add(int index, E element) {
rangeCheckForAdd(index);// 检查是否越界添加


ensureCapacityInternal(size + 1); // Increments modCount!! 是否需要扩容
System.arraycopy(elementData, index, elementData, index + 1, size - index);// 复制 index后数据,放到扩容后的数组中
elementData[index] = element;// 在index点添加数据
size++;// 长度加一
}

 
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);// 将index+1至size-1的数据复制到index至size-2的位置,即index+1变为index;size-1位置的数据前移后,size-1位置的元素仍存在,
elementData[--size] = null; // clear to let GC do its work(放弃引用,等待gc回收) size-1位置的引用指向null,删除完成


return oldValue;
}


 
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)// 遍历数组值
if (elementData[index] == null) {
fastRemove(index);// 删除index位置的数据
return true;
}
} else {
for (int index = 0; index < size; index++)// 遍历数组值
if (o.equals(elementData[index])) {
fastRemove(index);// 删除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);// 将index+1至size-1的数据复制到index至size-2的位置,即index+1变为index;size-1位置的数据前移后,size-1位置的元素仍存在,
elementData[--size] = null; // clear to let GC do its work(放弃引用,等待gc回收) size-1位置的引用指向null,删除完成
}

 
public void clear() {//删除数组中所有元素
modCount++;


// clear to let GC do its work
for (int i = 0; i < size; i++)
elementData[i] = null;// 遍历,将所有的引用都=null


size = 0;
}


public boolean addAll(Collection<? extends E> c) {
Object[] a = c.toArray();// 数组
int numNew = a.length;// 长度
ensureCapacityInternal(size + numNew); // Increments modCount判断是否需要扩容,如果需要,直接扩容
System.arraycopy(a, 0, elementData, size, numNew);// 将数组a从头复制到数组elementData中,elementData数组从size位置开始接收,长度是numNew
size += numNew;// elementData数组长度
return numNew != 0;
}

 
public boolean addAll(int index, Collection<? extends E> c) {
rangeCheckForAdd(index);// 判断插入点是否正确,不正确,thow异常


Object[] a = c.toArray();// 数组
int numNew = a.length;// 长度
ensureCapacityInternal(size + numNew); // Increments modCount判断是否需要扩容,如果需要,直接扩容


int numMoved = size - index;// index后面的数组长
if (numMoved > 0)// elementData数组index后有数据
System.arraycopy(elementData, index, elementData, index + numNew, numMoved);// elementData数组数据迁移,腾出numNew个空间,从index开始至index + numNew结束


System.arraycopy(a, 0, elementData, index, numNew);/// 将数组a从头复制到数组elementData中,从下标index开始,复制长度是numNew
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开始的位置,复制长度numMoved


// clear to let GC do its work
int newSize = size - (toIndex - fromIndex);// 剩余长度
for (int i = newSize; i < size; i++) {
elementData[i] = null;// 将newSize后包括newSize下标的数据设为null,等待gc回收
}
size = newSize;// 删除后长度
}

 
private void rangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));// 下标越界异常
}


/**
* A version of rangeCheck used by add and addAll.
*/
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) {// 删除与集合c中重合的元素
Objects.requireNonNull(c);// 检查指定的对象引用不是 null 。 是null抛异常
return batchRemove(c, false);
}

 
public boolean retainAll(Collection<?> c) {// 保留与集合c中重合的元素
Objects.requireNonNull(c);// 检查指定的对象引用不是 null 。 是null抛异常
return batchRemove(c, true);
}


private boolean batchRemove(Collection<?> c, boolean complement) {
final Object[] elementData = this.elementData;
int r = 0, w = 0;
boolean modified = false;
try {
for (; r < size; r++)
if (c.contains(elementData[r]) == complement)// 数组c是否包含elementData[r]
elementData[w++] = elementData[r]; // 将相等或者不等的数据赋值到elementData[w++]中
} finally {
// Preserve behavioral compatibility with AbstractCollection,
// even if c.contains() throws.
if (r != size) {// 为了防止比对结束以后elementData数组中又添加数据,比对一下数组最新长度size和r的长度
System.arraycopy(elementData, r, elementData, w, size - r);// 将r到size的数据赋值到从w开始,长度为size-r的数组中
w += size - r;// 数组长度
}
if (w != size) {
// clear to let GC do its work
for (int i = w; i < size; i++)
elementData[i] = null;// 遍历删除w下标以后包括w的数据
modCount += size - w;
size = w;
modified = true;
}
}
return modified;
}    
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值