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

如何将嵌套循环转换为符合Java 8风格的Stream操作?

Java 8 函数式风格等价实现

原代码的核心逻辑是跨批次和条目维护一个全局递增计数器,遍历所有AchBatchEntryDetail对象,完成以下操作:

  • 设置收件方名称(带计数器后缀)
  • 保留原金额(原代码中冗余赋值,但需保留逻辑)
  • 掩码账户号
  • 打印日志

以下是符合Java 8风格的等价实现:

AchFile dataRoot = unmarshalled.stream().findFirst().get();
AtomicInteger cntr = new AtomicInteger(1); // 用原子类维护全局递增计数器

dataRoot.getBatchRecords().stream()
        .flatMap(batch -> batch.getBatchEntries().stream()) // 扁平化批次到条目
        .flatMap(entry -> entry.getBatchEntryDetails().stream()) // 扁平化条目到明细
        .forEach(detail -> {
            int currentCnt = cntr.getAndIncrement(); // 获取当前计数并自增
            detail.setReceivingIndividualCompanyName("Client Name" + currentCnt);
            detail.setAmount(detail.getAmount()); // 保留原冗余逻辑
            String maskedAccount = randomizeAccountNumber(detail);
            detail.setDfiAccountNumber(maskedAccount);
            log.info("Masked detail record #{}", currentCnt);
        });

关键说明

  • 计数器的处理:原代码中cntr是跨循环的全局变量,Java 8流中不能直接使用普通可变int(会被编译器视为final),因此用AtomicInteger来实现线程安全的递增(即使串行流也适用,保持逻辑一致性)。
  • flatMap的作用:通过两次flatMap将三层嵌套结构(Batch -> Entry -> Detail)扁平化为AchBatchEntryDetail的流,避免嵌套循环。
  • forEach的使用:因为我们是对现有对象做原地修改(副作用操作),而非转换生成新对象,所以用forEach终端操作来执行逻辑——你之前注释的代码之所以无效,就是因为只调用了map/flatMap却没有触发终端操作,流是惰性执行的,不会实际运行。
  • 原逻辑的完整保留:包括冗余的detail.setAmount(detail.getAmount())和日志打印,确保与原代码行为完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 13:25:04