我有一个布尔字段列表,看起来像这样:
var lst = List.of(true, false, false, false)
;
有一个这样的物体:
public class GetBatchResponse {
String batchCompleted;
Integer totalCount;
Integer processed;
Integer pending;
}
上面的对象当前填充有这样的内容:
var resp = new GetBatchStatusResponse();
resp.setBatchCompleted(String.valueOf( !lst.contains(false));
resp.setTotalCount(lst.size());
resp.setProcessed((int)(lst.stream().filter(p ->p!=null && p == true).count()));
resp.setPending((int)(lst.stream().filter(p ->p==null && p == false).count()));
如何在单个循环中使用流 API 实现相同的效果?
p == null && p == false
没有意义。当p == null
时,p == false
会抛出一个NullPointerException
。
假设您的意思是
p == null || p == false
,与 p!=null && p == true
相反,您可以使用 partitioningBy
收集器。使用 counting
收集器作为下游,因为您想要每个组的计数。
var partitions = lst.stream().collect(
Collectors.partitioningBy(
p -> Objects.equals(p, true),
Collectors.counting()
)
);
然后,您可以将相应字段设置为
partitions.get(true)
和partitions.get(false)
。
resp.setProcessed((int)partitions.get(true))
resp.setPending((int)partitions.get(false))
基本上,您需要一个包含真/假/空计数的统计数据。我建议将 Stream.reduce(identity,accumulator,combiner) 与统计对象一起使用,并从中构建最终结果。
public record BooleanStatistic(int trueCount, int falseCount, int nullCount) {
public BooleanStatistic merge(BooleanStatistic other) {
return new BooleanStatistic(trueCount + other.trueCount, falseCount + other.falseCount, nullCount + other.nullCount);
}
public BooleanStatistic count(Boolean bool) {
if (bool == null) {
return new BooleanStatistic(trueCount, falseCount, nullCount + 1);
}
if (bool) {
return new BooleanStatistic(trueCount + 1, falseCount, nullCount);
}
return new BooleanStatistic(trueCount, falseCount + 1, nullCount);
}
public int total() {
return trueCount + falseCount + nullCount;
}
}
用途:
public class RandomStuff {
public static void main(String[] args) {
var lst = List.of(true, false, false, false);
BooleanStatistic statistic = lst.stream().reduce(new BooleanStatistic(0, 0, 0), BooleanStatistic::count, BooleanStatistic::merge);
System.out.println(statistic);
var result = new GetBatchResponse();
result.setBatchCompleted(String.valueOf(statistic.falseCount() == 0));
result.setTotalCount(statistic.total());
result.setProcessed(statistic.trueCount());
result.setPending(statistic.falseCount());
}
}