将嵌套循环转换为惯用的 Java 8 流运算符

问题描述 投票:0回答:1

以下遗留逻辑需要转换为 Java 8 函数式方法:

AchFile dataRoot = unmarshalled.stream().findFirst().get();
        
        List<AchBatch> batches = dataRoot.getBatchRecords();
        //batches.stream().flatMap(b -> b.getBatchEntries().stream().flatMap(e -> e.getBatchEntryDetails().stream().map(d -> d.setReceivingIndividualCompanyName("Client"))));
        
        for (AchBatch batch : batches) {
            int cntr = 1;
            for (AchBatchEntry entry : batch.getBatchEntries()) {
                Iterator<AchBatchEntryDetail> it = entry.getBatchEntryDetails().iterator();
                for (; it.hasNext(); cntr++ ) {
                    AchBatchEntryDetail detail = it.next();
                    detail.setReceivingIndividualCompanyName("Client Name"+cntr);
                    detail.setAmount(detail.getAmount());
                    
                    String maskedAccount = randomizeAccountNumber(detail);
                    
                    detail.setDfiAccountNumber(maskedAccount);
                    
                    log.info("Masked detail record #{}", cntr);
                }
            }
        }

展开此类嵌套循环结构的等效且惯用的 Java 8 语法是什么?

我已经开始将

flatMap
与常规
map
操作一起应用(如注释掉的部分所示),但我不太确定我是否走在正确的轨道上,希望得到一些指导。

java java-8 functional-programming java-stream
1个回答
1
投票

流式传输代码的真正问题是计数器和日志的使用。 无论如何,一个简单/可读的解决方案是不要从一开始就进行流式传输。 像这样的东西应该可以工作(显然无法测试):

AtomicInteger cntr = null;

Consumer<AchBatchEntryDetail> setCompany = d -> { int c = cntr.IncrementAndGet(); d.setReceivingIndividualCompanyName("Client Name"+c); log.info("Masked detail record #{}", c); };
Consumer<AchBatchEntryDetail> setAmount =  d -> d.setAmount(d.getAmount());
Consumer<AchBatchEntryDetail> setAccount = d -> d.setDfiAccountNumber(randomizeAccountNumber(d);
for (AchBatch batch : batches) {
    cntr = new AtomicInteger(); // new counter on each batch
    batch.stream()
         .map(AchBatch::getBatchEntries)
         .flatMap(Collection::stream)
         .map(AchBatchEntry::getBatchEntryDetails)
         .forEach(setCompany.andThen(setAmount).andThen(setAccount));
}
© www.soinside.com 2019 - 2024. All rights reserved.