Java List 接口(java.util.List)用于表示对象的有序序列。在 List 中,元素的插入、访问、迭代和删除操作均可以按照其在集合内部的出现顺序进行,这种有序性正是其被称为 "List" 的核心原因。
List 中的每个元素都对应一个索引值:第一个元素的索引为 0,第二个为 1,以此类推。索引本质上代表 "与列表起始位置的元素间隔数"—— 第一个元素因直接位于列表开端,故与起始位置的间隔为 0。
List 可以存储任何 Java 对象。若未通过泛型指定元素类型,甚至能在同一个 List 中混合存放不同类的对象,但这种用法在实际开发中并不常见。
作为 Java 标准接口,List 继承自 Collection 接口,是 Collection 体系中的重要子类型。
Java List 和 Set 接口非常相似,它们都表示元素集合。不过,它们之间也有一些明显的区别。这些差异反映在 List 和 Set 接口提供的方法中。主要区别如下:
(1)元素的重复性:List 允许同一元素多次出现,而 Set 则要求每个元素具有唯一性,不可重复存在。
(2) 元素的顺序性:List 中的元素存在明确的顺序,可按此顺序对元素进行迭代。Set 对其内部元素的存储顺序不做任何保证。
作为 Collection 的子类型,Collection 接口中的所有方法在 List 接口中也都可用。
由于 List 是一个接口,因此你需要实例化该接口的具体实现才能使用它。你可以在 Java 集合框架的 API 中选择以下 List 实现:
java.util.ArrayList:基于动态数组实现,查询效率高,增删元素(尤其中间位置)效率较低,线程不安全,是日常开发中最常用的 List 实现。
java.util.LinkedList:基于双向链表实现,增删元素效率高(尤其首尾操作),查询效率较低,同时可作为队列、栈使用,线程不安全。
java.util.Vector:与 ArrayList 类似的动态数组实现,但属于线程安全类(方法加锁),因此性能略低,如今已较少推荐使用。
java.util.Stack:继承自 Vector,是基于数组实现的栈结构,遵循后进先出(LIFO)原则,提供 push、pop、peek 等栈操作方法,线程安全但性能一般。
在这些实现中,ArrayList 是最常用的。
注意,在 java.util.concurrent 包中也有并发 List 实现,这些 List 将在 Java 并发编程教程中介绍。
创建 List 的实例很简单,可以通过创建实现了 List 接口的某个类的实例就可以了。例如:
List listA = new ArrayList(); List listB = new LinkedList(); List listC = new Vector(); List listD = new Stack();
上面代码创建了四个 List 实例,分别是不同的 List 子类。
默认情况下,你可以将任何对象放入列表中,但从 Java 5 开始,Java 泛型使得限制可以插入列表的对象类型成为可能。以下是一个示例:
List<String> list = new ArrayList<String>();
这个列表现在只能插入 String 的实例。然后,你可以访问并迭代其元素,而无需对它们进行强制类型转换。示例如下:
import java.util.*;
public class Demo {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("one");
list.add("two");
String val = list.get(0);
for(String item : list){
System.out.println(item);
}
}
}如果没有泛型,上面的示例将会是这样的:
import java.util.*;
public class Demo {
public static void main(String[] args) {
List list = new ArrayList();
list.add("one");
list.add("two");
String val = (String)list.get(0);
for(Object item : list){
System.out.println((String)item);
}
}
}需要注意的是,若要从 List 中检索 String 实例,需将其强制转换为 String 类型。这是因为:若 List 变量声明时未指定泛型类型,Java 编译器仅能识别该 List 存储的是 Object 实例,因此必须手动将其强转为你已知的具体类(或接口)类型。
在声明 List 变量时尽可能指定泛型类型,是一种推荐的编程实践。这样做有三大优势:
(1)能避免向 List 中插入错误类型的对象。
(2)从 List 检索对象时,无需再将其强转为实际类型。
(3)能让代码阅读者直观了解该 List 应存储的对象类型。
只有在具备充分且合理的理由时,才建议省略泛型类型。在本 Java List 教程的后续内容中,我将尽可能采用带有泛型的 List 示例进行讲解。
你可以使用 List 的 add() 方法向其中插入元素(对象)。例如:
List<String> listA = new ArrayList<>();
listA.add("element 1");
listA.add("element 2");
listA.add("element 3");上述代码向 List 中添加了 3 个字符串。
List 允许插入空(null)值,例如:
Object element = null; List<Object> list = new ArrayList<>(); list.add(element);
甚至,还能在指定的位置插入元素。List 接口有一个 add() 方法的版本,它将索引作为第一个参数,要插入的元素作为第二个参数。例如:
package com.hxstrive.java_collection;
import java.util.*;
public class CollectionDemo {
public static void main(String[] args) {
List<String> listA = new ArrayList<>();
listA.add("element 1");
listA.add("element 2");
listA.add("element 3");
// 插入到下标0的位置
listA.add(0, "element 4");
System.out.println(listA);
}
}运行结果:
[element 4, element 1, element 2, element 3]
如果列表(List)中已经包含元素,这些元素现在会在列表的内部序列中被进一步后移。在新元素插入到索引 0 之前原本位于索引 0 的元素,将会被移至索引 1,以此类推。
除了上述方法,List 还提供了一个批量添加元素的方法 addAll()。它会将参数列表中的元素逐一添加到当前列表,得到的列表(List)是这两个列表的并集。例如:
package com.hxstrive.java_collection;
import java.util.*;
public class CollectionDemo {
public static void main(String[] args) {
List<String> listSource = new ArrayList<>();
listSource.add("123");
listSource.add("456");
List<String> listDest = new ArrayList<>();
listSource.add("789");
listDest.addAll(listSource);
System.out.println("listDest=" + listDest);
}
}运行结果:
listDest=[123, 456, 789]
此示例将 listSource 中的所有元素添加到 listDest 中。
注意,addAll() 方法以一个 Collection 作为参数,因此你可以传入 List 或 Set 作为参数。换句话说,你可以使用 addAll() 将 List 或 Set 中的所有元素添加到一个 List 中。
你可以通过元素的索引从 List 中获取元素(索引从 0 开始),使用 get(int index) 方法来实现。例如:
package com.hxstrive.java_collection;
import java.util.*;
public class CollectionDemo {
public static void main(String[] args) {
List<String> listA = new ArrayList<>();
listA.add("element 0");
listA.add("element 1");
listA.add("element 2");
for(int i = 0; i < listA.size(); i++) {
System.out.println(listA.get(i));
}
}
}运行结果:
element 0 element 1 element 2
你可以使用以下两个方法中任意一个在 List 中查找元素:
indexOf() 用于查找给定元素在列表(List)中首次出现的索引。
lastIndexOf() 用于查找指定元素在列表中最后一次出现的索引位置。
例如:
package com.hxstrive.java_collection;
import java.util.*;
public class CollectionDemo {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("element 1"); // 0
list.add("element 3"); // 1
list.add("element 2"); // 2
list.add("element 3"); // 3
int index1 = list.indexOf("element 3"); // 首次出现
int index2 = list.lastIndexOf("element 3"); // 最后一次出现
System.out.println("index1 = " + index1); // index1 = 1
System.out.println("index2 = " + index2); // index2 = 3
}
}运行结果:
index1 = 1 index2 = 3
你可以使用 List 的 contains() 方法来检查 List 是否包含某个特定元素。例如:
package com.hxstrive.java_collection;
import java.util.*;
public class CollectionDemo {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("element 1");
list.add("element 2");
list.add("element 3");
boolean containsElement = list.contains("element 2");
System.out.println(containsElement);
containsElement = list.contains("element 4");
System.out.println(containsElement);
}
}运行结果:
true false
为了确定列表是否包含某个元素,列表会在内部遍历其元素,并将每个元素与作为参数传入的对象进行比较。这种比较会使用元素的 equals 方法来检查该元素是否与参数相等。
由于可以向列表(List)中添加空(null)值,因此实际上可以检查列表(List)中是否包含空(null)值。以下是检查列表(List)中是否包含空(null)值的方法:
package com.hxstrive.java_collection;
import java.util.*;
public class CollectionDemo {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("element 1");
list.add("element 2");
list.add(null);
boolean containsElement = list.contains(null);
System.out.println(containsElement);
}
}显然,如果传给 contains() 的输入参数是 null,那么 contains() 方法不会使用 equals() 方法来与每个元素进行比较,而是会使用 == 运算符。如下图:

你可以通过以下两种方法从 List 中移除元素:
remove(Object element) 用于从 List 中移除首次出现的指定元素(通过 equals() 方法判断相等性)。若元素存在且被成功移除,返回 true;若列表中无此元素,返回 false。此方法会改变元素的索引(移除位置后的元素索引自动减 1)。
remove(int index) 用于移除 List 中指定索引位置的元素,返回被移除的元素。索引需在 0 到 size()-1 范围内,否则会抛出 IndexOutOfBoundsException。同样,移除后该位置后的元素索引会减 1。
例如:
package com.hxstrive.java_collection;
import java.util.*;
public class CollectionDemo {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("element 1");
list.add("element 2");
list.add("element 3");
System.out.println("移除前:" + list);
boolean removeFlag = list.remove("element 2");
System.out.println(removeFlag ? "移除成功" : "移除失败");
removeFlag = list.remove("element 4"); // 不存在的元素
System.out.println(removeFlag ? "移除成功" : "移除失败");
System.out.println("移除后:" + list);
}
}运行结果:
移除前:[element 1, element 2, element 3] 移除成功 移除失败 移除后:[element 1, element 3]
以下是一个根据索引从 List 中移除元素的示例:
package com.hxstrive.java_collection;
import java.util.*;
public class CollectionDemo {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("element 1");
list.add("element 2");
list.add("element 3");
System.out.println("移除前:" + list);
String removeFlag = list.remove(2);
System.out.println(removeFlag + "移除成功");
try {
list.remove(3); // 不存在的元素
} catch (IndexOutOfBoundsException e) {
System.out.println("移除元素失败,下标越界。" + e.getMessage());
}
System.out.println("移除后:" + list);
}
}运行结果:
移除前:[element 1, element 2, element 3] element 3移除成功 移除元素失败,下标越界。Index: 3, Size: 2 移除后:[element 1, element 2]
List 接口包含一个 clear() 方法,调用该方法时会从列表中移除所有元素。从 List 中移除所有元素也称为清空 List。例如:
package com.hxstrive.java_collection;
import java.util.*;
public class CollectionDemo {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("element 1");
list.add("element 2");
System.out.println("清空前 list=" + list);
list.clear(); // 清空
System.out.println("清空后 list=" + list);
}
}运行结果:
清空前 list=[element 1, element 2] 清空后 list=[]
List 接口提供了 retainAll() 方法,其核心作用是保留当前 List 中所有同时存在于另一个 List 中的元素。换而言之,该方法会从调用它的 “目标 List” 中,移除所有在 “另一个 List” 里不存在的元素,最终使目标 List 成为两个列表的交集(仅包含两者共有的元素)。
需要注意的是,方法名是 retainAll()(末尾带有 All),而非 retain()。以下是调用 List 的 retainAll() 方法的 Java 示例:
package com.hxstrive.java_collection.list;
import java.util.ArrayList;
import java.util.List;
public class ListRetainAllExample {
public static void main(String[] args) {
// 1. 创建目标 List(待处理的列表)
List<String> fruits = new ArrayList<>();
fruits.add("apple");
fruits.add("banana");
fruits.add("orange");
fruits.add("grape");
// 2. 创建用于比对的 List(仅保留两者共有的元素)
List<String> favoriteFruits = new ArrayList<>();
favoriteFruits.add("apple");
favoriteFruits.add("grape");
favoriteFruits.add("mango");
// 3. 调用 retainAll() 方法:保留 fruits 中存在于 favoriteFruits 的元素
boolean isChanged = fruits.retainAll(favoriteFruits);
// 4. 输出结果
System.out.println("列表是否发生修改:" + isChanged); // 输出 true(有元素被移除)
System.out.println("处理后的 fruits 列表(交集):" + fruits); // 输出 [apple, grape]
}
}运行结果:
列表是否发生修改:true 处理后的 fruits 列表(交集):[apple, grape]
通过调用 List 的 size() 方法可以获取列表(List)中元素的数量。例如:
List<String> list = new ArrayList<>();
list.add("element 1");
list.add("element 2");
int size = list.size(); // 2
List 接口提供了 subList() 方法,其核心功能是从原始 List 中截取部分元素,生成一个新的子列表(子列表仍是原列表的视图,非独立副本)。
subList() 方法需传入两个参数,分别对应截取范围的起始索引与结束索引,规则如下:
起始索引:指定原始 List 中要纳入子列表的第一个元素的位置(包含该元素),索引值需满足 0 ≤ 起始索引 ≤ 结束索引。
结束索引:指定子列表的截止位置(不包含该索引对应的元素),索引值需满足 起始索引 ≤ 结束索引 ≤ 原始 List 长度。
这一取值逻辑与 Java 中 String 类的 substring() 方法完全一致,均遵循 “左闭右开” 的范围规则。
例如:
package com.hxstrive.java_collection.list;
import java.util.ArrayList;
import java.util.List;
public class SubListExample {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("element 1");
list.add("element 2");
list.add("element 3");
list.add("element 4");
// 从索引1(包含)到索引3(不包含)截取子列表
List<String> sublist = list.subList(1, 3);
// 输出原始列表和子列表内容
System.out.println("原始列表: " + list); // [element 1, element 2, element 3, element 4]
System.out.println("子列表(sublist): " + sublist); // [element 2, element 3]
// 注意:子列表是原始列表的视图,修改子列表会影响原始列表
sublist.set(0, "modified element");
System.out.println("修改子列表后,原始列表: " + list); // [element 1, modified element, element 3, element 4]
}
}运行结果:
原始列表: [element 1, element 2, element 3, element 4] 子列表(sublist): [element 2, element 3] 修改子列表后,原始列表: [element 1, modified element, element 3, element 4]
若需将 List 转换为 Set,可通过创建新的 Set 实例,并将 List 中的所有元素传入该 Set 来实现。由于 Set 本身具有 “元素不可重复” 的特性,在转换过程中会自动移除 List 中的重复元素,最终得到的 Set 会包含 List 中的全部非重复元素,且每个元素仅出现一次。
例如:
package com.hxstrive.java_collection.list;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
public class ListToSetExample {
public static void main(String[] args) {
// 1. 创建包含重复元素的 List
List<String> fruitList = new ArrayList<>();
fruitList.add("apple");
fruitList.add("banana");
fruitList.add("apple"); // 重复元素
fruitList.add("orange");
fruitList.add("banana"); // 重复元素
System.out.println("原始 List(含重复): " + fruitList);
// 2. 转换为 HashSet(不保证元素顺序)
Set<String> fruitHashSet = new HashSet<>(fruitList);
System.out.println("转换为 HashSet(去重,无序): " + fruitHashSet);
// 3. 转换为 LinkedHashSet(保留元素在 List 中的首次出现顺序)
Set<String> fruitLinkedHashSet = new LinkedHashSet<>(fruitList);
System.out.println("转换为 LinkedHashSet(去重,保序): " + fruitLinkedHashSet);
}
}运行结果:
原始 List(含重复): [apple, banana, apple, orange, banana] 转换为 HashSet(去重,无序): [banana, orange, apple] 转换为 LinkedHashSet(去重,保序): [apple, banana, orange]
你可以使用 List 的 toArray() 方法将 List 转换为 Java 数组。如果调用 toArray() 方法没有指定参数,则返回的是一个 Object[] 数组类型,需要手动进行类型强转。推荐使用携带参数的 toArray() 方法,这样就可以将一个 List 转换为特定类型的数组。 例如:
package com.hxstrive.java_collection.list;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ListToArrayExample {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("element 1");
list.add("element 2");
list.add("element 3");
list.add("element 3");
// 将List转换为Object数组
Object[] objects = list.toArray();
System.out.println("数组长度: " + objects.length); // 输出:4
System.out.println("数组元素: " + Arrays.toString(objects));
// 推荐:使用带参数的toArray()获取指定类型数组(避免强制转换)
String[] strings = list.toArray(new String[0]);
System.out.println("指定类型数组元素: " + Arrays.toString(strings));
}
}运行结果:
数组长度: 4 数组元素: [element 1, element 2, element 3, element 3] 指定类型数组元素: [element 1, element 2, element 3, element 3]
请注意,即使我们向 toArray() 方法传递一个大小为 0 的 String 数组,返回的数组也会包含列表中的所有元素。它的元素数量将与该列表的元素数量相同。
不仅可以将 List 转换为数组,数组也可以转换为 List,需要使用 Arrays.asList(),例如:
String[] values = new String[]{ "one", "two", "three" };
List<String> list = Arrays.asList(values);
System.out.println("list=" + list); // list=[one, two, three]
可以使用 Collections 的 sort() 方法对 List 进行排序。在前面“Java 集合:Collections 工具类中”中已经了解了,但在接下来的部分中,我将向你展示几种对 List 进行排序的方法。
如果 List 中包含的是实现了 java.lang.Comparable 接口的对象,那么这些对象可以相互比较。在这种情况下,你可以像这样对列表进行排序:
List<String> list = new ArrayList<>();
list.add("c");
list.add("b");
list.add("a");
Collections.sort(list);
System.out.println(list); // [a, b, c]注意, Java 的 String 类实现了 Comparable 接口,因此你可以使用 Collections 的 sort() 方法按照它们的自然顺序对其进行排序。
如果 List 中的对象没有实现 Comparable 接口,或者你希望按照不同于它们的 compare() 实现的顺序对对象进行排序,那么你需要使用 Comparator 实现(java.util.Comparator)。例如:
package com.hxstrive.java_collection;
import java.util.*;
public class CollectionDemo {
public static void main(String[] args) {
List<Car> list = new ArrayList<>();
list.add(new Car("Volvo V40" , "XYZ 201845", 5));
list.add(new Car("Citroen C1", "ABC 164521", 4));
list.add(new Car("Dodge Ram" , "KLM 845990", 2));
Collections.sort(list, new Comparator<Car>() {
@Override
public int compare(Car car1, Car car2) {
return car1.brand.compareTo(car2.brand);
}
});
list.forEach(System.out::println);
}
}
class Car{
public String brand;
public String numberPlate;
public int noOfDoors;
public Car(String brand, String numberPlate, int noOfDoors) {
this.brand = brand;
this.numberPlate = numberPlate;
this.noOfDoors = noOfDoors;
}
@Override
public String toString() {
return "Car{" +
"brand='" + brand + '\'' +
", numberPlate='" + numberPlate + '\'' +
", noOfDoors=" + noOfDoors +
'}';
}
}运行结果:
Car{brand='Citroen C1', numberPlate='ABC 164521', noOfDoors=4}
Car{brand='Dodge Ram', numberPlate='KLM 845990', noOfDoors=2}
Car{brand='Volvo V40', numberPlate='XYZ 201845', noOfDoors=5}注意,上面示例中的 Comparator 实现。该实现仅比较 Car 对象的 brand 字段。我们可以创建另一个Comparator 实现,用于比较车牌号,甚至是汽车的车门数量。
还可以使用 Lambda 来实现 Comparator。下面是一个示例,它使用 Comparator 接口的三种不同 lambda 实现对 Car 对象的 List 进行排序,每种实现都通过不同的字段来比较 Car 实例:
package com.hxstrive.java_collection;
import java.util.*;
public class CollectionDemo {
public static void main(String[] args) {
List<Car> list = new ArrayList<>();
list.add(new Car("Volvo V40" , "XYZ 201845", 5));
list.add(new Car("Citroen C1", "ABC 164521", 4));
list.add(new Car("Dodge Ram" , "KLM 845990", 2));
Comparator<Car> carBrandComparatorLambda =
(car1, car2) -> car1.brand.compareTo(car2.brand);
Comparator<Car> carNumberPlatComparatorLambda =
(car1, car2) -> car1.numberPlate.compareTo(car2.numberPlate);
Comparator<Car> carNoOfDoorsComparatorLambda =
(car1, car2) -> car1.noOfDoors - car2.noOfDoors;
System.out.println("根据brand排序:");
Collections.sort(list, carBrandComparatorLambda);
list.forEach(System.out::println);
System.out.println("根据numberPlate排序:");
Collections.sort(list, carNumberPlatComparatorLambda);
list.forEach(System.out::println);
System.out.println("根据noOfDoors排序:");
Collections.sort(list, carNoOfDoorsComparatorLambda);
list.forEach(System.out::println);
}
}
class Car{
public String brand;
public String numberPlate;
public int noOfDoors;
public Car(String brand, String numberPlate, int noOfDoors) {
this.brand = brand;
this.numberPlate = numberPlate;
this.noOfDoors = noOfDoors;
}
@Override
public String toString() {
return "Car{" +
"brand='" + brand + '\'' +
", numberPlate='" + numberPlate + '\'' +
", noOfDoors=" + noOfDoors +
'}';
}
}运行结果:
根据brand排序:
Car{brand='Citroen C1', numberPlate='ABC 164521', noOfDoors=4}
Car{brand='Dodge Ram', numberPlate='KLM 845990', noOfDoors=2}
Car{brand='Volvo V40', numberPlate='XYZ 201845', noOfDoors=5}
根据numberPlate排序:
Car{brand='Citroen C1', numberPlate='ABC 164521', noOfDoors=4}
Car{brand='Dodge Ram', numberPlate='KLM 845990', noOfDoors=2}
Car{brand='Volvo V40', numberPlate='XYZ 201845', noOfDoors=5}
根据noOfDoors排序:
Car{brand='Dodge Ram', numberPlate='KLM 845990', noOfDoors=2}
Car{brand='Citroen C1', numberPlate='ABC 164521', noOfDoors=4}
Car{brand='Volvo V40', numberPlate='XYZ 201845', noOfDoors=5}
你可以通过几种不同的方式迭代一个 List。常见的方式如下:
使用迭代器 Iterator
使用增强型for循环 for-each
使用 for 循环
使用 Stream API
迭代列表的第一种方法是使用迭代器(Iterator),例如:
List<String> list = new ArrayList<>();
list.add("first");
list.add("second");
list.add("third");
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}运行结果:
first second third
上述示例通过调用 List 接口的 iterator() 方法可以获得一个 Iterator。一旦获得了一个迭代器,就可以不断调用它的 hasNext() 方法,直到该方法返回 false 为止。在 while 循环内部,你调用 Iterator 接口的next() 方法来获取迭代器所指向的下一个元素。
迭代列表的第二种方法是使用 Java5 中新增的 for循环(也称为“for each”循环)。例如:
List<String> list = new ArrayList<>();
list.add("first");
list.add("second");
list.add("third");
for(String element : list) {
System.out.println(element);
}上述示例代码,for 循环会针对列表中的每个元素执行一次。
迭代列表的第三种方法是使用像这样的标准for循环,例如:
List<String> list = new ArrayList<>();
list.add("first");
list.add("second");
list.add("third");
for(int i=0; i < list.size(); i++) {
System.out.println(list.get(i));
}上述示例代码中,for 循环会创建一个 int 变量并将其初始化为 0。然后,只要 int 变量 i 小于 List 的大小,循环就会继续执行。在每次迭代中,变量 i 都会递增。在 for 循环内部,通过 List 的 get() 方法访问其中的元素,并将递增变量 i 作为参数传入。
迭代 List 的第四种方法是通过 Stream API。要迭代 List,你必须首先从该 List 中获取一个 Stream。在 Java 中,从 List 获取 Stream 是通过调用 List 的 stream() 方法来实现的。例如:
List<String> list = new ArrayList<>();
list.add("first");
list.add("second");
list.add("third");
list.stream().forEach(item -> {
System.out.println(item);
});上诉示例中,通过调用 List 的 stream() 方法,获取了表示该 List 中元素的 Stream。一旦获取到 List 中元素的 Stream,就可以通过调用其 forEach() 方法来迭代这个 Stream。
调用 forEach() 方法会使流在内部迭代流中的所有元素,并为流中的每个元素调用作为参数传递给 forEach() 方法的 Consumer 实例。