说明
- Java版本:1.8.0_231
ArrayList
- 底层由Object数组实现,具有数组的所有特性,实现了
RandomAccess
接口支持随机访问,非线程安全类型
Object[] elementData;
- 构造方法
- 创建一个空数组
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);
}
}
- add()方法及扩容机制
public boolean add(E e) {
ensureCapacityInternal(size + 1);
// 将元素e添加到末尾
elementData[size++] = e;
return true;
}
- 数组容量初始化
private static int calculateCapacity(Object[] elementData, int minCapacity) {
// 判断是否是为空数组,若为空,返回10;否则将返回arr.length + 1(第一次添加数据肯定是空的,第二次及后续就是arr.length +1)
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
- 判断是否到达扩容零界点
private void ensureExplicitCapacity(int minCapacity) {
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
// 核心 开始扩容
private void grow(int minCapacity) {
// 获取数组长度
int oldCapacity = elementData.length;
// 右移位运算得出扩容后的长度
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// 将扩容后的数据赋值给原数组
elementData = Arrays.copyOf(elementData, newCapacity);
}
在添加第一个元素时,就会调用grow()
方法进行扩容操作,但此时数组长度为0,扩容后的
LinkedList
- 底层由双向链表实现,实现了
Deque
接口,可以双向操作,不支持随机访问,非线程安全类型
// node节点
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
// 指向上一个节点
Node<E> first;
// 指向下一个节点
Node<E> last;
- 两个构造函数
- 构造一个空List
public LinkedList() {
}
- 一个有参构造函数
public LinkedList(Collection<? extends E> c) {
this();
addAll(c);
}sdss
- 链表追加节点至末尾
public boolean add(E e) {
linkLast(e);
return true;
}
// 这个就不解释,应该懂得
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
Vector
- 底层有Object数组实现,实现了
RandomAccess
接口,支持随机访问,线程安全类型
protected Object[] elementData;
- 三个构造函数(其实是一个)
- 赋予初始容量和扩容量
public Vector(int initialCapacity, int capacityIncrement) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
this.capacityIncrement = capacityIncrement;
}
- 使用默认的扩容量0
public Vector(int initialCapacity) {
this(initialCapacity, 0);
}
- 使用默认的初始容量10和初始容量0
public Vector() {
this(10);
}
- 添加元素与扩容机制
public synchronized void addElement(E obj) {
// 扩容
ensureCapacityHelper(elementCount + 1);
// 将新增元素添加到数组末尾
elementData[elementCount++] = obj;
}
private void ensureCapacityHelper(int minCapacity) {
// 第一次添加元素时,minCapacity=10,elementData.length = 0,这时不会进行扩容
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
// 获取数据的长度
int oldCapacity = elementData.length;
// 扩容核心:在创建数组时指定了capacityIncrement且大于0,扩容后的值为capacityIncrement+初始容量,反之为初始容量+初始容量,即两倍的初始容量
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
List接口主要实现类总结
- ArrayList和Vector底层基于数组实现,具有数组的所有特性且支持随机访问,其中Vector时线程安全的;在扩容机制上:
- ArrayList是1.5倍扩容,关键代码为
int newCapacity = oldCapacity + (oldCapacity >> 1);
即 10 --> 15; - Vector是2倍扩容,关键代码:
int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity);
,即:10 --> 20
- LinkedList是基于双向链表实现,可双向插入,插入删除快,查找慢
网站原文:https://www.haicheng.website/passages/source-code-analysis-01/