Java 流式传输列表并创建单个对象

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

我有一个布尔字段列表,看起来像这样:

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 实现相同的效果?

java stream java-17
2个回答
1
投票

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))

0
投票

基本上,您需要一个包含真/假/空计数的统计数据。我建议将 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());
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.