List 是 Java 集合框架(java.util 包)中核心的有序、可重复 集合接口,继承自 Collection 接口,支持通过索引(下标)快速访问、修改元素,是日常开发中最常用的集合类型之一。
一、什么是 List?
1. 核心定义
List 是 Collection 接口的子接口,用于存储有序、可重复的元素集合,其核心特征是:
- 有序性:元素的插入顺序与存储顺序一致,支持通过索引(0 起始)访问元素;
- 可重复性:允许存储多个相同的元素(包括
null); - 索引操作:提供了基于索引的增删改查方法(这是 List 与 Set 最核心的区别)。
2. 与其他核心集合的区别

二、List 接口核心方法(含继承 + 独有)
List 继承了 Collection 接口的基础方法(如 add(E)、remove(Object)、size()、isEmpty() 等),同时新增了基于索引的操作方法,核心方法如下:
1. 新增元素(基于索引)
java
// 1. 在列表末尾添加元素(继承自Collection)
boolean add(E e);
// 2. 在指定索引index处插入元素,后续元素后移(List独有)
void add(int index, E element);
// 3. 将另一个集合的所有元素添加到当前列表末尾
boolean addAll(Collection<? extends E> c);
// 4. 将另一个集合的所有元素插入到指定索引处
boolean addAll(int index, Collection<? extends E> c);
2. 删除元素(基于索引 / 元素)
java
// 1. 删除指定索引处的元素,返回被删除的元素(List独有)
E remove(int index);
// 2. 删除第一个匹配的元素(继承自Collection)
boolean remove(Object o);
// 3. 清空所有元素
void clear();
3. 修改元素(基于索引)
java
// 替换指定索引处的元素,返回被替换的旧元素(List独有)
E set(int index, E element);
4. 查询元素(基于索引 / 元素)
java
// 1. 获取指定索引处的元素(List独有)
E get(int index);
// 2. 返回第一个匹配元素的索引,无则返回-1(List独有)
int indexOf(Object o);
// 3. 返回最后一个匹配元素的索引,无则返回-1(List独有)
int lastIndexOf(Object o);
// 4. 判断集合是否包含指定元素(继承自Collection)
boolean contains(Object o);
5. 其他常用方法
java
// 1. 返回List的子列表(左闭右开区间),注意:子列表是原列表的视图,修改会相互影响
List<E> subList(int fromIndex, int toIndex);
// 2. 将List转为数组
Object[] toArray();
<T> T[] toArray(T[] a);
// 3. 获取迭代器(支持遍历)
Iterator<E> iterator();
// 4. Java 8+ 新增:forEach遍历(函数式接口)
void forEach(Consumer<? super E> action);
三、List 的主要实现类(重点)
List 是接口,无法直接实例化,需使用其实现类。日常开发中最常用的实现类有 4 个,核心差异在于底层数据结构 和性能特性:

关键补充:
ArrayList扩容机制:初始容量为 10,负载因子 0.75,当元素个数达到容量×负载因子时,扩容为原容量的 1.5 倍(避免频繁扩容,可初始化时指定容量优化);LinkedList除了 List 方法,还实现了Deque接口,支持addFirst()、addLast()、pollFirst()、pop()等队列 / 栈操作;CopyOnWriteArrayList适合读多写少(如配置缓存),写操作(add/remove)会复制原数组,开销较大,不适合频繁写的场景。
四、List 的使用(实战示例)
1. 实例化 List
推荐使用接口引用 + 实现类实例的方式(面向接口编程):
java
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
public class ListDemo {
public static void main(String[] args) {
// 1. ArrayList(默认容量10)
List<String> arrayList = new ArrayList<>();
// 初始化指定容量(优化扩容)
List<Integer> arrayList2 = new ArrayList<>(20);
// 2. LinkedList
List<String> linkedList = new LinkedList<>();
// 3. 线程安全的CopyOnWriteArrayList
List<String> safeList = new CopyOnWriteArrayList<>();
// 4. 不可变List(Java 9+,元素不可增删改)
List<String> immutableList = List.of("a", "b", "c");
}
}
2. 核心操作(增删改查)
java
List<String> list = new ArrayList<>();
// 增
list.add("Java"); // 末尾添加:[Java]
list.add(0, "Python"); // 索引0插入:[Python, Java]
list.addAll(Arrays.asList("C++", "Go")); // 末尾添加集合:[Python, Java, C++, Go]
// 查
String elem = list.get(1); // 获取索引1元素:Java
int index = list.indexOf("C++"); // 查找元素索引:2
boolean contains = list.contains("Go"); // 是否包含:true
// 改
String oldElem = list.set(2, "Rust"); // 替换索引2元素:[Python, Java, Rust, Go],oldElem=C++
// 删
list.remove(3); // 删除索引3元素:[Python, Java, Rust]
list.remove("Python"); // 删除元素:[Java, Rust]
System.out.println(list); // 输出:[Java, Rust]
3. 遍历 List(5 种常用方式)
java
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
// 1. 普通for循环(基于索引)
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i) + " "); // a b c
}
// 2. 增强for循环(foreach,推荐)
for (String s : list) {
System.out.print(s + " ");
}
// 3. 迭代器(Iterator)- 支持遍历中删除元素
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String s = iterator.next();
if (s.equals("b")) {
iterator.remove(); // 安全删除(避免ConcurrentModificationException)
}
System.out.print(s + " "); // a b c(删除后list变为[a, c])
}
// 4. Java 8+ forEach(函数式接口)
list.forEach(s -> System.out.print(s + " "));
// 5. Java 8+ Stream流遍历
list.stream().forEach(System.out::print);
4. 排序 List
List 支持自定义排序,核心用 Collections.sort()(旧版)或 List.sort()(Java 8+,推荐):
java
List<Integer> numList = new ArrayList<>(Arrays.asList(3, 1, 4, 2));
// 1. 自然排序(元素需实现Comparable接口,如Integer、String)
numList.sort(Comparator.naturalOrder()); // 升序:[1, 2, 3, 4]
// 2. 逆序排序
numList.sort(Comparator.reverseOrder()); // 降序:[4, 3, 2, 1]
// 3. 自定义对象排序(以User为例)
class User {
String name;
int age;
// 构造器、getter省略
}
List<User> userList = new ArrayList<>(Arrays.asList(
new User("张三", 25),
new User("李四", 20)
));
// 按年龄升序排序
userList.sort((u1, u2) -> u1.getAge() - u2.getAge());
// 或用Comparator.comparing(更简洁)
userList.sort(Comparator.comparingInt(User::getAge));
5. List 去重(保留顺序)
List 允许重复元素,去重常用 2 种方式:
java
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "a", "c"));
// 方式1:LinkedHashSet(保留插入顺序,去重)
List<String> distinctList1 = new ArrayList<>(new LinkedHashSet<>(list));
System.out.println(distinctList1); // [a, b, c]
// 方式2:Java 8+ Stream.distinct()(保留顺序)
List<String> distinctList2 = list.stream().distinct().collect(Collectors.toList());
6. 并发安全问题与解决
ArrayList、LinkedList 是线程不安全的,多线程修改时会抛 ConcurrentModificationException,解决方式:
java
// 方式1:使用Collections.synchronizedList(加锁,效率一般)
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
// 方式2:使用CopyOnWriteArrayList(读多写少,推荐)
List<String> safeList = new CopyOnWriteArrayList<>();
// 多线程操作示例
new Thread(() -> safeList.add("a")).start();
new Thread(() -> safeList.forEach(System.out::print)).start();
五、常见注意事项
subList视图特性 :subList(from, to)返回原列表的子视图,修改子列表或原列表都会相互影响,且子列表依赖原列表存在(原列表被销毁后子列表不可用);- 迭代器安全删除 :使用增强 for 循环或迭代器遍历的同时,不能用
list.remove()(会触发 fail-fast 机制抛异常),需用Iterator.remove(); - 不可变 List :
List.of()创建的列表不可增删改,否则抛UnsupportedOperationException; ArrayList初始化优化 :已知元素个数时,指定初始容量(如new ArrayList<>(100)),避免频繁扩容。