/*
今天晚上看了会ArrayList源码,研究了一下主要的函数。主要有以下几个函数:
add()
remove()
ensureCapacity()
grow()
hugeCapacity()
fastremove() (和remove稍有区别)
以及内部类Itr 实现了Iterator接口
基本分析写在注释里了。
*/
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
public ArrayList(int initialCapacity) {
// 如果指定大小,则new一个指定大小的数组
// 否则elementData为一个Oject类型的空数组(Oject[] EMPTY_ELEMENTDATA = {})
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() {
// 不传入任何参数,默认为空数组
// Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
// 通常size < elementData.length
// 去掉数组多余部分以减少需要存储的空间
public void trimToSize() {
modCount++;
if (size < elementData.length) {
elementData = (size == 0)
? EMPTY_ELEMENTDATA
: Arrays.copyOf(elementData, size);
}
}
public void ensureCapacity(int minCapacity) {
// 不是默认空数组则为0,否则为10
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;
// 如果传入参数大于minExpand,则增加容量,否则不增加
if (minCapacity > minExpand) {
ensureExplicitCapacity(minCapacity);
}
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(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) // 如果超过数组最大长度
// hugeCapacity中,如果minCapacity为负数,表明整型溢出,抛出OOM
// 大于MAX_ARRAY_SIZE则取Integer.MAX_VALUE否则取MAX_ARRAY_SIZE
// 当 newCapcity = (oldCapacity + (oldCapacity >> 1)) > MAX_ARRAY_SIZE
// && minCapacity < 0 时发生
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
public boolean add(E e) {
// 默认往后添加元素
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
public void add(int index, E element) {
// 在指定下表增加元素
// 越界检查
rangeCheckForAdd(index);
// 确保有size+1的容量,ensureCapacityInternal会调用ensureExplicitCapacity
ensureCapacityInternal(size + 1); // Increments modCount!!
// 将原数组index下标开始的元素复制到从index+1开始,也就是往后移,空出index下标位置
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index); // 旧值
int numMoved = size - index - 1;
if (numMoved > 0)
// 将index位置之后的元素往前移动
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
// 原本的最后一个设置成空,jvm会回收该空间
elementData[--size] = null; // clear to let GC do its work
// 返回旧值
return oldValue;
}
public boolean remove(Object o) {
// 区分空和不空,需要一次循环
// == 和 equals
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) {
// 和remove不同的地方就是不反回旧值且不进行越界检查
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
}
// 内部类Itr实现了Iterator接口
private class Itr implements Iterator<E> {
int cursor; // 迭代器中,指向当前元素的游标
int lastRet = -1; // 最后一次返回元素的下标,初始为-1
int expectedModCount = modCount; // 修改次数
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
public E next() {
// 如果在使用迭代器的过程中,用了ArrayList的修改操作,则会导致迭代器失效
// 因为ArrayList的add,remove操作会使得modCount++,使得modCount!=expectedModCount
checkForComodification();
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() {
// 在第一次使用next后才能进行remove
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount; // 使用迭代器的remove不会造成迭代器失效
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
}
Java ArrayList部分源码研究
最新推荐文章于 2024-09-13 14:25:05 发布