Java ArrayList与LinkedList 源码浅析
首先我们先来看看ArrayList
ArrayList继承了AbstractList抽象类;实现了Serializable,Cloneable,RandomAccess接口
首先看几个成员变量
private static final int DEFAULT_CAPACITY = 10;默认初始值大小,为10private static final Object[] EMPTY_ELEMENTDATA = {};private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMPTYDATA = {}transient Object[] elementData;存放元素的数组private int size;元素的数量
构造方法
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
当new ArrayList<E>()不指定大小时,使用默认大小空数组初始化
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);
}
}
add(e)
会先调用ensureCapacitvInternal(size+1) 保证有足够的容量去新增一个元素
在ensureCapacitvInternal(size+1)中先调用calculateCapacity(minCapacity)获取最小的minCapcacity,如果ementData==DEFAULTCAPACITY_EMPTY_ELEMPTYDATA 就返回DEFAULT_CAPACITY,其余情况返回传入的minCapacity(size+1);
在调用ensureExplicitCapacity(minCapacity)会确保在minCapacity > ementData的条件下调用grow(minCapacity)扩容,在任何条件下都会modCount++;
ArrayList的扩容机制
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
// 每次扩容原容量的1.5
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);
}
newCapcacity为oldCapacity的1.5倍
- 若newCapacity < minCapacity,newCapacity就被赋值为oldCapacity
- 若newCapacity > MAX_ARRAY_SIZE,就调用
hugeCapacity在hugeCapacity中 minCapacity < 0 就抛出OOM,其他情况返回 minCapacity > MAX_ARRAY_SIZE? Integer.MAX_VALUE:MAX_ARRAY_SIZE - 调用Arrays.copy()将扩容后的数组赋值给ementData.
add(e,idx)
先rangeCheckForAdd()判断index > size- 还是调用
ensureCapacityInternalmodCount++ - 调用System.arraycopy(),
size++
LinkedList
Node类
```java
public static Class Node<E> {
E item;
Node<E> next;
Node<E> prev;
public Node<E>(Node<E> prev,E e,Node<E> next){
this.item = e;
this.next = next;
this.prev = prev;
}
add(e)
public boolean add(E e) {
linkLast(e);
return true;
}
void linkFirst(E e) {
final Node<E> f = first;
final Node<E> newNode = new Node<>(null,e,f);
if (last == null) {
last = newNode;
} else {
f.prev = newNode;
}
size++;
modeCount++;
}
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l,e,null);
if (l == null) {
first = newNode;
} else {
l.next = newNode;
}
size++;
modCount++;
}