ArrayList中的默认属性初始化信息.
package java.util;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
// RandomAccess是一个标记接口,实现之后可以实现对arraylist的快速访问。
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
private static final long serialVersionUID = 8683452581122892189L;
/**
* ArrayList默认初始容量
*/
private static final int DEFAULT_CAPACITY = 10;
/**
* 空数组
*/
private static final Object[] EMPTY_ELEMENTDATA = {};
/**
* 默认空数组
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
/**
* ArrayList底层的数组对象---elementData
*/
transient Object[] elementData;
/**
*数组中元素的个数
*/
private int size;
/**
*modCount为容器结构修改次数,用来作为容器迭代器的fail-fast机制底层支持
*/
protected transient int modCount = 0;
/**
* elementData数组的最大容量
*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
}
ArrayList初始化方法(3个)
/**
* 无参构造函数,底层构造一个空数组
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
/**
* 指定容量的构造函数
*/
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);
}
}
/**
* 将一个集合转换为ArrayList
*/
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0) {
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;
}
}
ArrayList的基本方法----add方法
/**
* 向list尾部添加元素。
* 1. 首先ensureCapacityInternal方法判断是否需要扩容
* 若初始化时arrayList为空则添加第一个元素的时候自动扩容为 10
* 当容器需要扩容时每次扩容量为当前容量的 1.5 倍
* 2. 向扩容后的容器尾部添加元素,并使size属性加一
*/
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
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);
}
/**
* 聊一聊 grow 方法。
* 1. grow 方法的 minCapacity 参数是elementData数组此时最少需要的数组容量。
* 2. 当我们的 arrayList 以单个元素的模式行为进行添加时,arrayList是以当前容量的1.5倍
* 进行扩容的。
* 3. 当我们的 arrayList 以集合元素的模式行为进行添加时,由于每次添加的集合元素数量不一
* 定为 1,因此我们很有可能遇到一种情况就是arrayList以 1.5 倍容量进行扩容之后依然无法
* 满足我们的元素存储空间需求,此时 arrayList 会执行 grow 方法中的
* newCapacity = minCapacity 语句将数组容量重新定义成我们所需要 minCapacity
* 容量大小。
* 4. 例如,假如我们的arrayList此时存在10个元素,当我们再次执行 list.add(E e) 方法时,
* arrayList 会进行扩容,将容量变为 15。
* 但是当我们执行list.addAll(Collection<? extends E> c) 方法并且集合 c 中的元素数
* 量大于 15,(假如为 19),那么arrayList会直接将容量增加到 19 。
*/
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;
}
// -------------------------------------------------------------------------------------
/**
* 向列表的指定位置添加元素
* 1. 检查index索引位置是否合法
* 2. 判断容器在添加元素之前是否需要扩容
* 3. 调用System.arraycopy函数使得插入位置以后的元素全体后移
* 4. 在指定的位置插入元素,并使 size 属性加一
*/
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
private void rangeCheckForAdd(int index) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
ArrayList的基本方法----addAll方法
/**
* 1. 将集合参数转换成数组类型
* 2,. 判断数组是否需要扩容
* 3. 将集合数组添加到原数组的尾部,并增加size属性值
*/
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);
size += numNew;
return numNew != 0;
}
/**
* 1. 检查索引参数是否合法
* 2. 判断数组是否需要扩容
* 3. 使用System.arraycopy函数构造新数组,并更新size属性值
*/
public boolean addAll(int index, Collection<? extends E> c) {
rangeCheckForAdd(index);
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); // Increments modCount
int numMoved = size - index;
if (numMoved > 0)
System.arraycopy(elementData, index, elementData, index + numNew,
numMoved);
System.arraycopy(a, 0, elementData, index, numNew);
size += numNew;
return numNew != 0;
}
ArrayList的基本方法----remove方法
/**
* 索引删除,元素删除完成之后将最后位置置空,以便垃圾收集器能够回收
*/
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
//--------------------------------------------------------------------------------------
/**
* 元素删除
*/
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; // clear to let GC do its work
}
//--------------------------------------------------------------------------------------
/**
* 清空列表,并更新size属性值
*/
public void clear() {
modCount++;
// clear to let GC do its work
for (int i = 0; i < size; i++)
elementData[i] = null;
size = 0;
}
//--------------------------------------------------------------------------------------
/**
* 清空列表,并更新size属性值
*/
public boolean removeAll(Collection<?> c) {
Objects.requireNonNull(c);
return batchRemove(c, false);
}
public static <T> T requireNonNull(T obj) { //Object类中的方法,判断obj是否为空
if (obj == null)
throw new NullPointerException();
return obj;
}
/**
* 1. 建立一个当前目标数组的引用
* 2. 循环遍历,找出所有在集合中没有出现过的元素组建成一个新的elementData数组
* 3. 进行数组空值处理
*/
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)
elementData[w++] = elementData[r];
} finally {
// 当try块出现异常时会进入此 if 语句块
//作用:拷贝在出现异常之后的所有元素到新的elementData数组中,
//并更新w的值防止下一条语句块将数据清空。
if (r != size) {
System.arraycopy(elementData, r,
elementData, w,
size - r);
w += size - r;
}
//当try块成功执行时会直接进入此 if 语句块
//作用:将赋值完成之后的新的elementData数组无用的元素置空
//并同步更新 size 属性值和 modCount 属性值。
if (w != size) {
// clear to let GC do its work
for (int i = w; i < size; i++)
elementData[i] = null;
modCount += size - w;
size = w;
modified = true;
}
}
return modified;
}
ArrayList迭代器:
ArrayList迭代器是以内部类的方式实现的。
private class Itr implements Iterator<E> {
int cursor; // 下一个迭代元素的索引位置
int lastRet = -1; // 最后一个迭代元素返回的索引位置
int expectedModCount = modCount; //迭代过程中的修改次数
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification(); //进行fail-fast判断检查
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification(); //fail-fast判断检查
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount; //同步更新modCount的值
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
@Override
@SuppressWarnings("unchecked")
public void forEachRemaining(Consumer<? super E> consumer) {
Objects.requireNonNull(consumer);
final int size = ArrayList.this.size;
int i = cursor;
if (i >= size) {
return;
}
final Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length) {
throw new ConcurrentModificationException();
}
while (i != size && modCount == expectedModCount) {
consumer.accept((E) elementData[i++]);
}
// update once at end of iteration to reduce heap write traffic
cursor = i;
lastRet = i - 1;
checkForComodification();
}
final void checkForComodification() { // fail-fast机制的底层实现
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
//--------------------------------------------------------------------------------------
private class ListItr extends Itr implements ListIterator<E> {
ListItr(int index) { //传入开始迭代元素的索引
super();
cursor = index;
}
public boolean hasPrevious() {
return cursor != 0;
}
public int nextIndex() {
return cursor;
}
public int previousIndex() {
return cursor - 1;
}
@SuppressWarnings("unchecked")
public E previous() {
checkForComodification();
int i = cursor - 1;
if (i < 0)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i;
return (E) elementData[lastRet = i];
}
public void set(E e) {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.set(lastRet, e);
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
public void add(E e) {
checkForComodification();
try {
int i = cursor;
ArrayList.this.add(i, e);
cursor = i + 1;
lastRet = -1;
expectedModCount = modCount; //更新modCount
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
}
// 返回迭代器
public ListIterator<E> listIterator() {
return new ListItr(0);
}
public Iterator<E> iterator() {
return new Itr();
}
到这里我们应该会发现当我们在迭代ArrayList时是不能跳过迭代器对他的结构进行修改的,每当我们进行迭代操作的时候,迭代器总会去判断modCount与expectedModCount值是否相等,当我们在迭代过程中调用了ArrayList的函数去修改列表结构之后,modCount值便会加一,因此便会抛出ConcurrentModificationException异常。所以我们只能调用迭代器的add和remove方法进行列表元素的添加和删除操作,因为在使用迭代器进行列表结构的变化时,也会同时更新modCount和expectedModCount的值使之对应。
ArrayList子列表的实现---SubList内部类
/**
* 1. 首先进行索引范围合法性检查
* 2. 返回一个子列表对象
*/
public List<E> subList(int fromIndex, int toIndex) {
subListRangeCheck(fromIndex, toIndex, size);
return new SubList(this, 0, fromIndex, toIndex);
}
static void subListRangeCheck(int fromIndex, int toIndex, int size) {
if (fromIndex < 0)
throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
if (toIndex > size)
throw new IndexOutOfBoundsException("toIndex = " + toIndex);
if (fromIndex > toIndex)
throw new IllegalArgumentException("fromIndex(" + fromIndex +
") > toIndex(" + toIndex + ")");
}
private class SubList extends AbstractList<E> implements RandomAccess {
private final AbstractList<E> parent;
private final int parentOffset;
private final int offset;
int size;
SubList(AbstractList<E> parent,
int offset, int fromIndex, int toIndex) {
this.parent = parent;
this.parentOffset = fromIndex;
this.offset = offset + fromIndex;
this.size = toIndex - fromIndex;
this.modCount = ArrayList.this.modCount;
}
/....../set get等操作列表数据的方法
}
subList是ArrayList的一个内部类,所以当我们通过SubList方法取得arrayList的子列表元素之后,若是通过subList对列表数据进行更新,那么父元素arrayList也会被同时更新。
网友评论