在 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);
// 生成試劑@Overridepublic 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 -> LongLong reagentId = TypeUtils.safeToLong(idObj);reagentIdList.add(reagentId.intValue());});// 返回生成的試劑return reagentMapper.selectByIds(reagentIdList);} else {// 返回空集合return new ArrayList<>();}}
?