如何用Java Stream单循环处理布尔列表生成GetBatchStatusResponse对象?
使用Java Stream API单次循环填充GetBatchStatusResponse对象
问题场景
现有布尔类型列表示例:
var lst = List.of(true, false, false, false);
对应的实体类定义:
public class GetBatchStatusResponse { String batchCompleted; Integer totalCount; Integer processed; Integer pending; // 实际使用需补充getter/setter方法 public void setBatchCompleted(String batchCompleted) { this.batchCompleted = batchCompleted; } public void setTotalCount(Integer totalCount) { this.totalCount = totalCount; } public void setProcessed(Integer processed) { this.processed = processed; } public void setPending(Integer pending) { this.pending = pending; } }
原填充逻辑需要多次遍历列表(调用contains、两次stream().filter().count()),现在需要通过Stream API单次循环完成完全相同的填充逻辑。
解决方案
方案一:使用reduce实现单次遍历统计
利用reduce方法将列表元素归约为一个统计数组,一次性计算出所有需要的指标:
// 数组索引定义:0=processed数量,1=pending数量,2=是否存在false(1表示存在) int[] stats = lst.stream() .reduce(new int[]{0, 0, 0}, (acc, bool) -> { if (Boolean.TRUE.equals(bool)) { acc[0]++; } else { acc[1]++; // 仅当明确为false时标记存在 if (Boolean.FALSE.equals(bool)) { acc[2] = 1; } } return acc; }, (a, b) -> { // 并行流场景下的合并逻辑,串行流不会触发 a[0] += b[0]; a[1] += b[1]; a[2] |= b[2]; return a; }); var resp = new GetBatchStatusResponse(); resp.setBatchCompleted(String.valueOf(stats[2] == 0)); resp.setTotalCount(lst.size()); resp.setProcessed(stats[0]); resp.setPending(stats[1]);
方案二:使用collect结合临时统计类(可读性更强)
定义一个临时统计类存储中间结果,通过collect完成单次遍历收集:
// 临时统计类,用于承载单次遍历的中间数据 class StatusStats { int processed = 0; int pending = 0; boolean hasFalse = false; } StatusStats stats = lst.stream() .collect(StatusStats::new, (stat, bool) -> { if (Boolean.TRUE.equals(bool)) { stat.processed++; } else { stat.pending++; if (Boolean.FALSE.equals(bool)) { stat.hasFalse = true; } } }, (stat1, stat2) -> { // 并行流合并逻辑 stat1.processed += stat2.processed; stat1.pending += stat2.pending; stat1.hasFalse = stat1.hasFalse || stat2.hasFalse; }); var resp = new GetBatchStatusResponse(); resp.setBatchCompleted(String.valueOf(!stats.hasFalse)); resp.setTotalCount(lst.size()); resp.setProcessed(stats.processed); resp.setPending(stats.pending);
关键说明
- 两种方案均仅遍历列表一次,避免了原逻辑多次遍历的性能开销
- 完全兼容原逻辑的
null处理:null会被计入pending,且不会影响batchCompleted的判断(只有false会导致batchCompleted为"false") - 并行流的合并逻辑已实现,支持大列表的并行处理
内容的提问来源于stack exchange,提问作者Akash tiwari
相关产品推荐
相关产品推荐

