一、ArrayList
- 可以添加多个null元素
- 底层用数组来实现
- 非线程安全,但是效率高
1. 扩容机制
1. 底层维护了一个Object类型的数组 elementData
transient Object[] elementData;
2. 当创建新的ArrayList时, 如果使用的无参构造器, 则elementData初始容量为0
第一次添加,则扩容为10, 如果需要再次扩容,则扩容elementData 为1.5倍
3. 使用指定大小的构造器,则 elementData为指定大小
如果需要扩容,则扩容为1.5 倍
2. 扩容实现
private static void copyArr(){
String[] arr = {"FIRST", "SECOND", "THIRD"};
System.out.println("arr地址:" + arr);
arr = Arrays.copyOf(arr, 5);
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
System.out.println("新的arr地址:" + arr);
}
二、Vector
1. 底层维护了Object类型的数组存放元素, Object[] elementData
2. 线程安全的,基本每个方法都带了 synchronized
1. 扩容机制
1. 如果是无参构造,则数组长度默认为10,如果满了后按2倍扩容
2. 有参构造指定,后续满了后按照2倍扩容
三、LinkedList
- 底层实现 《双向链表》 和 《双端队列》
- 可以添加任意元素,元素可以重复,包含null
- 线程不安全
数据结构
- 维护了两个属性, first last,分别指向首节点和尾节点
- 每个节点(Node对象),里面又维护了 prev、next、item三个属性
prev指向前一个节点, next指向后一个节点, item保存实际值
- LinkedList的元素的添加和删除,不是通过数组完成,效率相对较高

1.模拟双向链表
package com.erick.feature.collection.d01;
import java.util.LinkedList;
public class Demo03 {
public static void main(String[] args) {
LinkedList<String> list = new LinkedList<>();
method01();
}
private static void method01() {
Node<String> erickNode = new Node<>("Erick");
Node<String> tomNode = new Node<>("Tom");
Node<String> jackNode = new Node<>("Jack");
erickNode.next = tomNode;
tomNode.next = jackNode;
jackNode.pre = tomNode;
tomNode.pre = erickNode;
Node<String> first = erickNode;
Node<String> last = jackNode;
while (true) {
if (first != null) {
System.out.println(first.toString());
first = first.next;
} else {
break;
}
}
System.out.println("=================");
while (true) {
if (last != null) {
System.out.println(last.toString());
last = last.pre;
} else {
break;
}
}
Node<String> newNode = new Node<>("Merry");
erickNode.next = newNode;
newNode.pre = erickNode;
tomNode.pre = newNode;
newNode.next = tomNode;
first = erickNode;
System.out.println("=============");
while (true) {
if (first != null) {
System.out.println(first.toString());
first = first.next;
} else {
break;
}
}
}
}
class Node<T> {
private T item;
public Node pre;
public Node next;
public Node(T item) {
this.item = item;
}
@Override
public String toString() {
return "Node--" + item;
}
}
四、选择
- 项目中多是用来读,所以ArrayList用的相对比较多
| 底层结构 | 增删效率 | 改查效率 | 线程安全 |
---|
ArrayList | 可变数组 | 较低,数组扩容 | 较高 | N |
LinkedList | 双向链表 | 较高,链表追加 | 较低 | N |
Vector | 可变数组 | 较低,数组扩容 | 较高 | Y |