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());
详解
  1. filter(s -> s.length() > 3)
  • 参数形式: 一个 Lambda 表达式​ s -> s.length() > 3。
  • 参数作用: 它定义了一个过滤条件(一个返回布尔值的函数)。
  • 详细拆解:
    s: 这是 Lambda 表达式的参数,它代表流中当前正在处理的单个元素(在这里是列表里的一个字符串)。
    ->: 将参数和函数体分开。
    s.length() > 3: 这是函数体,是一个布尔表达式。它会对每个元素 s进行判断。
    整体意思: 对于流中的每一个元素 s,判断它的长度是否大于3。如果为 true,则元素保留;如果为 false,则被过滤掉。
  1. map(String::toUpperCase)
  • 参数形式: 一个 方法引用​ String::toUpperCase。
  • 参数作用: 它定义了一个转换函数,指定如何将输入元素转换成另一种形式的输出元素。
  • 详细拆解:
    String: 这指明了方法 toUpperCase所属的类。它告诉 map操作:“你将处理的是 String类型的对象”。
    ::: 方法引用操作符,可以看作是 ->调用特定方法的一种简洁写法。
    toUpperCase: 这是要调用的具体方法名。
    等价 Lambda 表达式: 这完全等价于 map(s -> s.toUpperCase())。
    执行过程: 对于流中传入的每一个字符串元素(例如 “hello”),map操作会对其调用 “hello”.toUpperCase()方法,并将返回值(“HELLO”)放入新的流中。所以,String::toUpperCase这个参数,就是传入给 map用于执行转换的具体动作。
  1. sorted()
    这个无参重载版本使用自然顺序(对于 String就是字典序)排序。它不需要额外参数来指定如何比较。

  2. 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 集合框架的第一步。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐