在 Java 中,List.forEach()
是 Java 8 引入的一种简洁的遍历集合元素的方法。它基于函数式编程思想,接受一个 Consumer
函数式接口作为参数,用于对集合中的每个元素执行操作。
基本语法
java
复制
下载
list.forEach(consumer);
使用示例
1. 使用 Lambda 表达式
java
复制
下载
import java.util.Arrays; import java.util.List; public class ForEachExample { public static void main(String[] args) { List<String> languages = Arrays.asList("Java", "Python", "C++", "JavaScript"); // 使用 Lambda 表达式遍历 languages.forEach(lang -> System.out.println(lang)); // 简化版:方法引用(推荐) languages.forEach(System.out::println); } }
2. 自定义操作
java
复制
下载
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); // 对每个元素进行平方操作 numbers.forEach(n -> { int square = n * n; System.out.print(square + " "); // 输出:1 4 9 16 25 });
3. 修改外部变量(需注意线程安全)
java
复制
下载
List<Integer> nums = Arrays.asList(10, 20, 30); int[] sum = {0}; // 使用数组绕过 final 限制 nums.forEach(n -> sum[0] += n); System.out.println(sum[0]); // 输出:60
关键注意事项
-
无法中断/跳过
forEach
不支持break
或continue
,如需条件终止,请改用传统循环或 Stream API:java
复制
下载
// 使用 Stream 实现条件过滤 languages.stream() .filter(lang -> lang.startsWith("J")) .forEach(System.out::println); // 输出 Java, JavaScript
-
执行顺序
对ArrayList
等有序集合按索引顺序执行,对HashSet
等无序集合顺序不确定。 -
并发修改风险
禁止在遍历中修改集合结构(增删元素),否则会抛出ConcurrentModificationException
:java
复制
下载
// 错误示例:尝试删除元素 List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3)); list.forEach(n -> { if (n == 2) list.remove(n); // 抛出异常! });
-
与
for-each
循环的区别特性 list.forEach()
传统 for-each
循环语法简洁度 ⭐⭐⭐ ⭐⭐ 支持 break
/continue
❌ ✔️ 异常处理 需在 Lambda 内处理 可在外部处理 性能 接近 接近
何时使用?
-
✅ 适合简单遍历操作(如打印、计算)
-
✅ 需要代码简洁时
-
❌ 需要中断循环或跳过元素时
-
❌ 需要修改集合结构时
完整示例
java
复制
下载
import java.util.*; public class AdvancedExample { public static void main(String[] args) { List<String> colors = new ArrayList<>(); colors.add("Red"); colors.add("Green"); colors.add("Blue"); // 1. 打印元素 colors.forEach(color -> System.out.println(color.toUpperCase())); // 2. 条件操作(无过滤) colors.forEach(color -> { if (color.length() > 3) { System.out.println("Long color: " + color); } }); // 3. 修改外部对象 StringBuilder result = new StringBuilder(); colors.forEach(result::append); // 拼接字符串 System.out.println(result); // 输出:RedGreenBlue } }
💡 提示:对于复杂操作(过滤、映射等),推荐结合
Stream API
使用,能获得更强大的功能:java
复制
下载
list.stream() .filter(s -> s.length() > 4) .map(String::toUpperCase) .forEach(System.out::println);
// 生成试剂
@Override
public List<Reagent> generate(List<Integer> idList) {
if (!idList.isEmpty()) {
List<Integer> reagentIdList = new ArrayList<>();
idList.forEach(ckDetailId -> {
// id 接收器,用于接收插入数据时生成的自增 id 值
Map<String, Object> idHolder = new HashMap<>();
// 插入数据
reagentMapper.insertByCkDetailId(ckDetailId, idHolder);
// 获取插入数据后的自增 id 值(键名 generatedId 与 XML 配置一致 idHolder.get("generatedId") keyProperty="idHolder.generatedId")
Object idObj = idHolder.get("generatedId");
// 类型安全转换 Object -> Long
Long reagentId = TypeUtils.safeToLong(idObj);
reagentIdList.add(reagentId.intValue());
});
// 返回生成的试剂
return reagentMapper.selectByIds(reagentIdList);
} else {
// 返回空集合
return new ArrayList<>();
}
}