You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中forEach循环遇SQLException时如何终止并继续外层循环

解决方案:终止嵌套forEach并保留外层循环

方案1:用普通for循环替代stream的forEach

这是最直接的实现方式,普通for循环原生支持break关键字,可以直接终止当前的切片循环,同时外层的文件迭代不受影响:

for (Iterator iterator = notLoadedFiles.iterator(); iterator.hasNext();) {
    SwapReport swapReport = (SwapReport) iterator.next();
    Reader reader = Files.newBufferedReader(Paths.get(swapReport.getFilePath()));
    CSVParser csvParser = new CSVParser(reader, CSVFormat.DEFAULT);
    List<CSVRecord> initList = csvParser.getRecords();
    
    CSVRecord csvRecord = initList.stream().filter(record -> record.get(0).endsWith("@xxx.com")).findAny().orElse(null);
    if (csvRecord != null) {
        List<List<CSVRecord>> output = ListUtils.partition(initList, chunkSize);

        // 替换stream.forEach为增强for循环
        for (List<CSVRecord> slice : output) {
            String inParams = slice.stream()
                    .filter(record -> !record.get(0).endsWith("@xxx.com"))
                    .map(record -> "'" + record.get(0) + "'")
                    .collect(Collectors.joining(","));
            try {
                setAccountData(inParams);
            } catch (SQLException e) {  
                // 终止当前切片循环,外层for继续处理下一个文件
                break;
            }
        }
    }
}

方案2:用原子标志位控制stream迭代终止

如果不想放弃stream写法,可以用AtomicBoolean作为终止标志,在lambda中检查标志位来提前终止后续迭代:

import java.util.concurrent.atomic.AtomicBoolean;

for (Iterator iterator = notLoadedFiles.iterator(); iterator.hasNext();) {
    SwapReport swapReport = (SwapReport) iterator.next();
    Reader reader = Files.newBufferedReader(Paths.get(swapReport.getFilePath()));
    CSVParser csvParser = new CSVParser(reader, CSVFormat.DEFAULT);
    List<CSVRecord> initList = csvParser.getRecords();
    
    CSVRecord csvRecord = initList.stream().filter(record -> record.get(0).endsWith("@xxx.com")).findAny().orElse(null);
    if (csvRecord != null) {
        List<List<CSVRecord>> output = ListUtils.partition(initList, chunkSize);

        AtomicBoolean shouldStop = new AtomicBoolean(false);
        output.stream().forEach(slice -> {
            // 标志位为true时直接跳过当前迭代
            if (shouldStop.get()) {
                return;
            }
            String inParams = slice.stream()
                    .filter(record -> !record.get(0).endsWith("@xxx.com"))
                    .map(record -> "'" + record.get(0) + "'")
                    .collect(Collectors.joining(","));
            try {
                setAccountData(inParams);
            } catch (SQLException e) {  
                // 设置终止标志,后续切片不再处理
                shouldStop.set(true);
            }
        });
    }
}

方案3:抛出非检查异常中断stream迭代

自定义一个RuntimeException,在捕获SQLException时抛出它,外层捕获后直接继续下一个文件的处理:

// 自定义非检查异常
class SliceProcessingException extends RuntimeException {
    public SliceProcessingException(Throwable cause) {
        super(cause);
    }
}

// 主逻辑代码
for (Iterator iterator = notLoadedFiles.iterator(); iterator.hasNext();) {
    SwapReport swapReport = (SwapReport) iterator.next();
    Reader reader = Files.newBufferedReader(Paths.get(swapReport.getFilePath()));
    CSVParser csvParser = new CSVParser(reader, CSVFormat.DEFAULT);
    List<CSVRecord> initList = csvParser.getRecords();
    
    CSVRecord csvRecord = initList.stream().filter(record -> record.get(0).endsWith("@xxx.com")).findAny().orElse(null);
    if (csvRecord != null) {
        List<List<CSVRecord>> output = ListUtils.partition(initList, chunkSize);

        try {
            output.stream().forEach(slice -> {
                String inParams = slice.stream()
                        .filter(record -> !record.get(0).endsWith("@xxx.com"))
                        .map(record -> "'" + record.get(0) + "'")
                        .collect(Collectors.joining(","));
                try {
                    setAccountData(inParams);
                } catch (SQLException e) {  
                    // 抛出异常终止整个stream迭代
                    throw new SliceProcessingException(e);
                }
            });
        } catch (SliceProcessingException e) {
            // 捕获异常后不做额外处理,外层循环继续下一个文件
            // 可在此处添加日志记录:e.printStackTrace();
        }
    }
}

内容的提问来源于stack exchange,提问作者angus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 03:46:13