【java】List接口详解
List 接口及其父接口常用方法详解
在 Java 集合框架中,List 是最常用、最核心的接口之一。无论是在业务开发、数据处理还是框架源码中,List 都有极高的出镜率。
本文将系统梳理:
- List 的继承结构
- List 的核心特性
- List 及其父接口 Collection 的常用方法
- 常见遍历方式
- 与 Stream API 的结合使用
- 常见使用技巧
本文专注于 List 接口本身的方法体系,不涉及具体实现类(如 ArrayList、LinkedList),这些内容会在后续文章中详细讲解。
一、List 接口概述
1️⃣ List 的继承关系
List 是 Java 集合框架中的一个接口,它继承自 Collection 接口。
public interface List<E> extends Collection<E> {
}
因此:
- Collection 定义的所有方法
- List 自身扩展的方法
都属于我们需要掌握的内容。
2️⃣ List 的核心特性
List 与其他集合类型(如 Set)最大的区别在于:
| 特性 | 说明 |
|---|---|
| 有序性 | 元素按照插入顺序存储 |
| 可重复 | 允许添加重复元素 |
| 支持索引 | 可以通过下标访问元素 |
| 动态扩容 | 底层自动扩展容量 |
简而言之:List = 有序 + 可重复 + 支持索引
3️⃣ List 自身常用方法
List 接口在 Java 8 中新增了 sort 方法(Collection 无此方法),并提供了 toArray 等实用操作。这些方法是 List 专属的核心能力,强烈建议优先使用而非依赖 Collections 工具类:
| 方法 | 说明 | 示例 |
|---|---|---|
sort(Comparator<? super E> comparator) |
Java 8 引入的专属方法,使用指定比较器排序列表,避免 Collections.sort() 的额外调用。 |
list.sort(Comparator.naturalOrder()); // 自然顺序(升序)排序 list.sort(Comparator.reverseOrder()); // 降序 list.sort(Comparator.comparing(String::length)); // 按长度排序 |
toArray() |
继承自 Collection 的常用方法,但因 List 高频使用,需强调其用法。返回包含所有元素的数组,可指定类型避免 ClassCastException。 |
// 转换为 Object[] Object[] array = list.toArray(); // 转换为指定类型(推荐) String[] stringArray = list.toArray(new String[0]); |
replaceAll(UnaryOperator<E> operator) |
Java 8 新增,批量替换元素(等价于 stream().map().collect(),但更高效)。 |
list.replaceAll(String::toUpperCase); // 全部转大写 |
removeIf(Predicate<? super E> filter) |
Java 8 新增,按条件删除元素(替代 iterator.remove() 的冗长写法)。 |
list.removeIf(s -> s.startsWith(“a”)); // 删除以 ‘a’ 开头的元素 |
关键说明:
sort优先级:list.sort(Comparator.naturalOrder())比Collections.sort(list)更简洁、更高效(避免创建临时列表)。toArray用法:new String[0]是最佳实践(JDK 规范),能确保返回指定类型的数组,避免类型转换异常。replaceAll/removeIf:这些方法是 Java 8 Stream API 的“同步优化”,在列表操作中比stream().filter().map()更高效(无需创建中间流)。
二、Collection 接口中的常用方法
由于 List 继承自 Collection,以下方法同样适用于 List。
1️⃣ 添加操作
boolean add(E e);
boolean addAll(Collection<? extends E> c);
| 方法 | 说明 |
|---|---|
| add | 添加单个元素 |
| addAll | 添加一个集合中的所有元素 |
2️⃣ 删除操作
boolean remove(Object o);
boolean removeAll(Collection<?> c);
void clear();
| 方法 | 说明 |
|---|---|
| remove | 删除第一个匹配元素 |
| removeAll | 删除所有匹配元素 |
| clear | 清空集合 |
3️⃣ 判断与查询
boolean contains(Object o);
boolean containsAll(Collection<?> c);
boolean isEmpty();
int size();
| 方法 | 说明 |
|---|---|
| contains | 是否包含某元素 |
| containsAll | 是否包含某集合 |
| isEmpty | 是否为空 |
| size | 元素数量 |
4️⃣ 迭代相关
Iterator<E> iterator();
用于遍历集合。
三、List 接口扩展方法(核心重点)
List 在 Collection 基础上新增了“索引操作”能力。
1️⃣ 基于索引的添加
void add(int index, E element);
boolean addAll(int index, Collection<? extends E> c);
作用:在指定位置插入元素。
2️⃣ 基于索引的访问
E get(int index);
通过下标访问元素。
3️⃣ 查找元素位置
int indexOf(Object o);
int lastIndexOf(Object o);
| 方法 | 说明 |
|---|---|
| indexOf | 第一次出现位置 |
| lastIndexOf | 最后一次出现位置 |
4️⃣ 修改元素
E set(int index, E element);
替换指定索引处的元素。
5️⃣ 删除指定位置元素
E remove(int index);
返回被删除元素。
6️⃣ 子列表视图
List<E> subList(int fromIndex, int toIndex);
⚠️ 注意:
- 左闭右开
[fromIndex, toIndex) - 返回的是“视图”,不是新集合
- 修改子列表会影响原列表
四、List 常见使用示例
List<String> list = new ArrayList<>();
list.add("苹果");
list.add("香蕉");
list.add("橙子");
// 插入
list.add(1, "葡萄");
// 获取
String value = list.get(0);
// 查找
int index = list.indexOf("香蕉");
// 替换
list.set(0, "西瓜");
// 删除
list.remove("橙子");
list.remove(1);
// 子列表
List<String> sub = list.subList(0, 1);
五、List 的遍历方式
遍历是开发中最常见的操作。
1️⃣ 普通 for 循环(适合需要索引场景)
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
2️⃣ 增强 for 循环
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> iterator = list.listIterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
支持:
- 正向遍历
- 反向遍历
- 遍历中修改元素
六、List 与 Stream API 结合(Java 8+)
Stream 让集合操作更加函数式。
1️⃣ 创建 Stream
list.stream();
list.parallelStream();
2️⃣ 常见操作
// 过滤
list.stream()
.filter(s -> s.startsWith("a"));
// 转换
list.stream()
.map(String::toUpperCase);
// 去重
list.stream()
.distinct();
// 排序
list.stream()
.sorted();
// 收集
list.stream()
.collect(Collectors.toList());
3️⃣ 综合示例
List<String> result = list.stream()
.filter(s -> s.length() > 3)
.map(String::toUpperCase)
.sorted()
.collect(Collectors.toList());
详解
- filter(s -> s.length() > 3)
- 参数形式: 一个 Lambda 表达式 s -> s.length() > 3。
- 参数作用: 它定义了一个过滤条件(一个返回布尔值的函数)。
- 详细拆解:
s: 这是 Lambda 表达式的参数,它代表流中当前正在处理的单个元素(在这里是列表里的一个字符串)。
->: 将参数和函数体分开。
s.length() > 3: 这是函数体,是一个布尔表达式。它会对每个元素 s进行判断。
整体意思: 对于流中的每一个元素 s,判断它的长度是否大于3。如果为 true,则元素保留;如果为 false,则被过滤掉。
- map(String::toUpperCase)
- 参数形式: 一个 方法引用 String::toUpperCase。
- 参数作用: 它定义了一个转换函数,指定如何将输入元素转换成另一种形式的输出元素。
- 详细拆解:
String: 这指明了方法 toUpperCase所属的类。它告诉 map操作:“你将处理的是 String类型的对象”。
::: 方法引用操作符,可以看作是 ->调用特定方法的一种简洁写法。
toUpperCase: 这是要调用的具体方法名。
等价 Lambda 表达式: 这完全等价于 map(s -> s.toUpperCase())。
执行过程: 对于流中传入的每一个字符串元素(例如 “hello”),map操作会对其调用 “hello”.toUpperCase()方法,并将返回值(“HELLO”)放入新的流中。所以,String::toUpperCase这个参数,就是传入给 map用于执行转换的具体动作。
-
sorted()
这个无参重载版本使用自然顺序(对于 String就是字典序)排序。它不需要额外参数来指定如何比较。 -
collect(Collectors.toList())
- 参数形式: 一个 收集器 Collectors.toList()。
- 参数作用: 它定义了终端操作的收集策略,即如何将流中的元素汇总成一个结果。
- 详细拆解:
Collectors: 是一个工具类,提供了很多静态工厂方法来创建常见的收集器。
.toList(): 是 Collectors类的一个静态方法。调用它会返回一个特定的Collector实现对象。
这个参数的作用: 你把这个“收集器”传入给 collect方法,就是在命令它:“请按照 toList()这个收集器规定的办法(即:创建一个新的 List,将所有元素按顺序添加进去),把流里的数据收集起来。”
七、开发中常见注意点
✔ List 允许重复元素
✔ 索引从 0 开始
✔ subList 返回的是视图
✔ 删除元素时注意 remove(int) 与 remove(Object) 的区别
✔ 多线程环境下需要额外处理(本文不展开)
八、总结
本文系统梳理了:
- List 的继承结构
- Collection 的通用方法
- List 的索引扩展方法
- 常见遍历方式
- Stream API 结合使用
掌握 List 的接口方法体系,是深入理解 Java 集合框架的第一步。
更多推荐



所有评论(0)