Java 中的 List 接口有哪些实现类?
·
Java 中的 List 接口实现类
1. List 接口实现类概览
List (接口)
├── ArrayList - 最常用的实现,基于动态数组
├── LinkedList - 基于双向链表
├── Vector - 线程安全的动态数组(已过时)
├── Stack - 继承自 Vector,栈实现(已过时)
├── CopyOnWriteArrayList - 写时复制的线程安全列表
├── AbstractList - 抽象类,提供部分实现
├── AbstractSequentialList - 抽象类,为顺序访问优化
├── Arrays.asList() - 返回固定大小的列表
├── Collections.emptyList() - 空列表
├── Collections.unmodifiableList() - 不可变列表
├── Collections.synchronizedList() - 同步列表
└── 第三方实现
├── FastList (Eclipse Collections)
├── TreeList (Apache Commons Collections)
└── GapList (Koloboke)
2. 核心实现类详解
2.1 ArrayList
import java.util.*;
public class ArrayListExample {
public static void main(String[] args) {
// 创建 ArrayList
List<String> list = new ArrayList<>();
// 指定初始容量
List<Integer> numbers = new ArrayList<>(100);
// 从其他集合创建
List<String> copy = new ArrayList<>(list);
// 添加元素
list.add("Apple");
list.add("Banana");
list.add("Orange");
// 在指定位置插入
list.add(1, "Grape");
// 批量添加
List<String> fruits = Arrays.asList("Mango", "Peach");
list.addAll(fruits);
// 访问元素
String first = list.get(0);
// 修改元素
list.set(0, "Cherry");
// 删除元素
list.remove("Banana"); // 按值删除
list.remove(0); // 按索引删除
// 查找元素
boolean contains = list.contains("Apple");
int index = list.indexOf("Orange");
// 获取大小
int size = list.size();
// 判断是否为空
boolean empty = list.isEmpty();
// 转换为数组
String[] array = list.toArray(new String[0]);
// 清空列表
list.clear();
// 遍历方式
// 1. for 循环
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
// 2. for-each
for (String item : list) {
System.out.println(item);
}
// 3. Iterator
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
// 4. ListIterator(双向遍历)
ListIterator<String> listIterator = list.listIterator();
while (listIterator.hasNext()) {
System.out.println(listIterator.next());
}
// 5. Stream API (Java 8+)
list.stream().forEach(System.out::println);
}
}
特点:
- 基于动态数组实现
- 随机访问快 O(1)
- 插入删除慢 O(n)
- 非线程安全
- 允许 null 元素
- 允许重复元素
适用场景:
- 频繁随机访问
- 尾部插入删除
- 数据量可预估
2.2 LinkedList
import java.util.*;
public class LinkedListExample {
public static void main(String[] args) {
// 创建 LinkedList
LinkedList<String> list = new LinkedList<>();
// 添加元素
list.add("A");
list.add("B");
list.add("C");
// 头部添加
list.addFirst("Start");
// 尾部添加
list.addLast("End");
// 在指定位置插入
list.add(2, "Middle");
// 获取首尾元素
String first = list.getFirst();
String last = list.getLast();
// 删除首尾元素
list.removeFirst();
list.removeLast();
// 作为栈使用
list.push("Top"); // 压栈
String top = list.pop(); // 弹栈
String peek = list.peek(); // 查看栈顶
// 作为队列使用
list.offer("QueueItem"); // 入队
String queueItem = list.poll(); // 出队
String queuePeek = list.peek(); // 查看队首
// 双向遍历
ListIterator<String> iterator = list.listIterator();
while (iterator.hasNext()) {
System.out.println("Next: " + iterator.next());
}
while (iterator.hasPrevious()) {
System.out.println("Previous: " + iterator.previous());
}
// 转换为数组
String[] array = list.toArray(new String[0]);
}
}
特点:
- 基于双向链表实现
- 随机访问慢 O(n)
- 插入删除快 O(1)
- 非线程安全
- 允许 null 元素
- 允许重复元素
- 可作为栈、队列、双端队列使用
适用场景:
- 频繁插入删除
- 头部/尾部操作
- 实现栈/队列
2.3 Vector
import java.util.Vector;
public class VectorExample {
public static void main(String[] args) {
// 创建 Vector
Vector<String> vector = new Vector<>();
// 指定初始容量和容量增量
Vector<Integer> numbers = new Vector<>(100, 50);
// 添加元素(所有方法都是同步的)
vector.add("A");
vector.add("B");
// 访问元素
String element = vector.get(0);
// Vector 特有的方法
vector.addElement("C"); // 等同于 add()
String firstElement = vector.firstElement();
String lastElement = vector.lastElement();
// 容量相关
int capacity = vector.capacity();
vector.ensureCapacity(200); // 确保最小容量
vector.trimToSize(); // 调整容量到实际大小
// 复制到数组
String[] array = new String[vector.size()];
vector.copyInto(array);
}
}
特点:
- 线程安全(所有方法都同步)
- 基于动态数组
- 性能较差(同步开销)
- 已过时,不推荐使用
- 允许 null 元素
适用场景:
- 需要线程安全的旧代码
- 不推荐新项目使用
2.4 Stack
import java.util.Stack;
public class StackExample {
public static void main(String[] args) {
// 创建 Stack
Stack<String> stack = new Stack<>();
// 压栈
stack.push("First");
stack.push("Second");
stack.push("Third");
// 查看栈顶元素
String top = stack.peek(); // "Third"
// 弹栈
String popped = stack.pop(); // "Third"
// 搜索元素(从栈顶开始,返回位置)
int position = stack.search("Second"); // 1
// 判断是否为空
boolean empty = stack.empty();
// Stack 继承自 Vector,也有 Vector 的方法
int size = stack.size();
}
}
特点:
- 继承自 Vector
- 后进先出(LIFO)
- 线程安全
- 已过时,推荐使用
ArrayDeque - 允许 null 元素
适用场景:
- 需要栈结构的旧代码
- 不推荐新项目使用
2.5 CopyOnWriteArrayList
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.Iterator;
public class CopyOnWriteArrayListExample {
public static void main(String[] args) {
// 创建 CopyOnWriteArrayList
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
// 添加元素
list.add("A");
list.add("B");
list.add("C");
// 批量添加
list.addAll(Arrays.asList("D", "E", "F"));
// 读操作(无锁)
String element = list.get(0);
boolean contains = list.contains("B");
int size = list.size();
// 写操作(会创建新数组)
list.add("G");
list.remove("A");
list.set(0, "NewB");
// 迭代器(弱一致性)
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
// 迭代期间可以安全修改列表
list.add("H"); // 不会影响当前迭代
}
// 并发场景示例
Runnable reader = () -> {
for (String item : list) {
System.out.println("Reading: " + item);
}
};
Runnable writer = () -> {
list.add("New Item");
System.out.println("Added new item");
};
// 多个线程可以同时读取
new Thread(reader).start();
new Thread(reader).start();
// 写操作会创建新副本,不影响正在进行的读操作
new Thread(writer).start();
}
}
特点:
- 写时复制策略
- 线程安全
- 读操作无锁,性能高
- 写操作需要复制数组,成本高
- 迭代器弱一致性,不会抛出
ConcurrentModificationException - 允许 null 元素
适用场景:
- 读多写少的并发场景
- 事件监听器列表
- 配置信息列表
3. 工具类创建的 List
3.1 Arrays.asList()
import java.util.*;
public class ArraysAsListExample {
public static void main(String[] args) {
// 创建固定大小的列表
List<String> list = Arrays.asList("A", "B", "C");
// 从数组创建
String[] array = {"X", "Y", "Z"};
List<String> listFromArray = Arrays.asList(array);
// 访问元素
String element = list.get(0);
// 遍历
for (String item : list) {
System.out.println(item);
}
// ⚠️ 注意:不能添加或删除元素
// list.add("D"); // 抛出 UnsupportedOperationException
// list.remove(0); // 抛出 UnsupportedOperationException
// 可以修改元素
list.set(0, "NewA");
// 修改数组会影响列表
array[0] = "NewX";
System.out.println(listFromArray.get(0)); // "NewX"
// 修改列表会影响数组
listFromArray.set(1, "NewY");
System.out.println(array[1]); // "NewY"
// 创建可修改的列表
List<String> modifiableList = new ArrayList<>(Arrays.asList("A", "B", "C"));
modifiableList.add("D"); // 可以添加
}
}
3.2 Collections 工具方法
import java.util.*;
public class CollectionsListExample {
public static void main(String[] args) {
// 空列表(不可变)
List<String> emptyList = Collections.emptyList();
// emptyList.add("A"); // 抛出 UnsupportedOperationException
// 单元素列表(不可变)
List<String> singletonList = Collections.singletonList("OnlyOne");
// singletonList.add("B"); // 抛出 UnsupportedOperationException
// 不可变列表
List<String> original = Arrays.asList("A", "B", "C");
List<String> unmodifiableList = Collections.unmodifiableList(original);
// unmodifiableList.add("D"); // 抛出 UnsupportedOperationException
// 同步列表(线程安全)
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
syncList.add("A");
syncList.add("B");
// 迭代时需要手动同步
synchronized (syncList) {
for (String item : syncList) {
System.out.println(item);
}
}
// checkedList(类型安全)
List rawList = new ArrayList();
List<String> checkedList = Collections.checkedList(rawList, String.class);
// checkedList.add(123); // 编译通过,运行时抛出 ClassCastException
// nCopies(创建包含 n 个相同元素的列表)
List<String> repeatedList = Collections.nCopies(5, "Repeat");
System.out.println(repeatedList); // [Repeat, Repeat, Repeat, Repeat, Repeat]
}
}
4. List.of() (Java 9+)
import java.util.List;
public class ListOfExample {
public static void main(String[] args) {
// 创建不可变列表
List<String> list1 = List.of("A", "B", "C");
List<Integer> list2 = List.of(1, 2, 3, 4, 5);
// 空列表
List<String> emptyList = List.of();
// 单元素列表
List<String> singletonList = List.of("OnlyOne");
// 访问元素
String element = list1.get(0);
// 遍历
for (String item : list1) {
System.out.println(item);
}
// ⚠️ 不可修改
// list1.add("D"); // 抛出 UnsupportedOperationException
// list1.set(0, "NewA"); // 抛出 UnsupportedOperationException
// ⚠️ 不允许 null 元素
// List<String> listWithNull = List.of("A", null, "C"); // 抛出 NullPointerException
// 转换为可修改列表
List<String> modifiableList = new ArrayList<>(List.of("A", "B", "C"));
modifiableList.add("D"); // 可以添加
}
}
5. 性能对比
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
public class ListPerformanceComparison {
public static void main(String[] args) {
int size = 100000;
// 测试 ArrayList
List<Integer> arrayList = new ArrayList<>();
long start = System.nanoTime();
for (int i = 0; i < size; i++) {
arrayList.add(i);
}
long arrayListAdd = System.nanoTime() - start;
// 测试 LinkedList
List<Integer> linkedList = new LinkedList<>();
start = System.nanoTime();
for (int i = 0; i < size; i++) {
linkedList.add(i);
}
long linkedListAdd = System.nanoTime() - start;
// 测试 Vector
Vector<Integer> vector = new Vector<>();
start = System.nanoTime();
for (int i = 0; i < size; i++) {
vector.add(i);
}
long vectorAdd = System.nanoTime() - start;
// 测试 CopyOnWriteArrayList
CopyOnWriteArrayList<Integer> cowList = new CopyOnWriteArrayList<>();
start = System.nanoTime();
for (int i = 0; i < size; i++) {
cowList.add(i);
}
long cowListAdd = System.nanoTime() - start;
System.out.println("添加 " + size + " 个元素耗时:");
System.out.println("ArrayList: " + arrayListAdd + " ns");
System.out.println("LinkedList: " + linkedListAdd + " ns");
System.out.println("Vector: " + vectorAdd + " ns");
System.out.println("CopyOnWriteArrayList: " + cowListAdd + " ns");
// 测试随机访问
start = System.nanoTime();
for (int i = 0; i < size; i++) {
arrayList.get(i);
}
long arrayListGet = System.nanoTime() - start;
start = System.nanoTime();
for (int i = 0; i < size; i++) {
linkedList.get(i);
}
long linkedListGet = System.nanoTime() - start;
System.out.println("\n随机访问 " + size + " 次耗时:");
System.out.println("ArrayList: " + arrayListGet + " ns");
System.out.println("LinkedList: " + linkedListGet + " ns");
// 测试头部插入
start = System.nanoTime();
arrayList.add(0, -1);
long arrayListInsert = System.nanoTime() - start;
start = System.nanoTime();
linkedList.add(0, -1);
long linkedListInsert = System.nanoTime() - start;
System.out.println("\n头部插入耗时:");
System.out.println("ArrayList: " + arrayListInsert + " ns");
System.out.println("LinkedList: " + linkedListInsert + " ns");
}
}
6. 选择指南
| 实现类 | 线程安全 | 随机访问 | 插入删除 | 适用场景 |
|---|---|---|---|---|
| ArrayList | 否 | O(1) | O(n) | 默认选择,频繁查询 |
| LinkedList | 否 | O(n) | O(1) | 频繁插入删除,实现栈/队列 |
| Vector | 是 | O(1) | O(n) | 旧代码,不推荐 |
| Stack | 是 | O(n) | O(1) | 旧代码,推荐 ArrayDeque |
| CopyOnWriteArrayList | 是 | O(1) | O(n) | 读多写少的并发场景 |
7. 使用建议
默认选择
// 大多数情况下使用 ArrayList
List<String> list = new ArrayList<>();
需要频繁插入删除
// 使用 LinkedList
List<String> list = new LinkedList<>();
需要线程安全
// 读多写少:CopyOnWriteArrayList
List<String> list = new CopyOnWriteArrayList<>();
// 读写均衡:synchronizedList
List<String> list = Collections.synchronizedList(new ArrayList<>());
实现栈
// 推荐使用 ArrayDeque
Deque<String> stack = new ArrayDeque<>();
stack.push("A");
String top = stack.pop();
实现队列
// 推荐使用 ArrayDeque
Deque<String> queue = new ArrayDeque<>();
queue.offer("A");
String front = queue.poll();
创建不可变列表
// Java 9+
List<String> immutableList = List.of("A", "B", "C");
// Java 8
List<String> immutableList = Collections.unmodifiableList(Arrays.asList("A", "B", "C"));
8. 总结
Java 中的 List 接口有多种实现类,每种都有其特定的使用场景:
- ArrayList - 最常用,适合大多数场景
- LinkedList - 适合频繁插入删除
- Vector/Stack - 已过时,不推荐使用
- CopyOnWriteArrayList - 适合读多写少的并发场景
- 工具类方法 - 用于创建特殊类型的列表
在实际开发中,ArrayList 通常是默认选择,只有在特定需求下才考虑其他实现类。
更多推荐




所有评论(0)