使用 Java 8 计算 true 的总布尔值

Count the total boolean value of true using Java 8

我正在使用 java 8。我有一个 class Operator,它有 3 个字段。

class Operator{
    private String type;
    private boolean updateRequested;
    private boolean deleteRequested;
}

我有 Operator 的列表。我只想根据 type 计算 updatedRequesteddeleteRequested 其值为 true 并添加到 Map<String,Result>

的地图中
class Result{
    private int deleteReqCount;
    private int updateReqCount;
}

预期结果

{
    "Cricket":{ deleteReqCount:10, updateReqCount:0},  // count only the value == `true`
    "Football":{ deleteReqCount:2, updateReqCount:10}, // count only the value == `true`
}

这道题有点简单,我确实用了for循环和if条件。但我对 Stream api 和 Collectors 框架印象深刻。我是初学者,所以尝试 list.stream().collect(Collectors.groupingBy(g -> g.getType())); 但无法更进一步。

提前致谢

这是一个使用 Collectors.toMap

的实现
class Operator {
    public String type;
    public boolean updateRequested;
    public boolean deleteRequested;
    Operator(String type, boolean updateRequested, boolean deleteRequested) {
        this.type = type;
        this.updateRequested = updateRequested;
        this.deleteRequested = deleteRequested;
    }
}

class Result {
    public int deleteReqCount;
    public int updateReqCount;
    Result(int deleteReqCount, int updateReqCount) {
        this.deleteReqCount = deleteReqCount;
        this.updateReqCount = updateReqCount;
    }

    @Override
    public String toString() {
        return "Result{" +
                "deleteReqCount=" + deleteReqCount +
                ", updateReqCount=" + updateReqCount +
                '}';
    }
}

Map<String, Result> solve(List<Operator> operatorList) {
    return operatorList.stream()
            .collect(Collectors.toMap(
                    v -> v.type,
                    v -> new Result(v.deleteRequested ? 1 : 0, v.updateRequested ? 1 : 0),
                    (result, result2) -> {
                        int deleteReqCount = result.deleteReqCount + result2.deleteReqCount;
                        int updateReqCount = result.updateReqCount + result2.updateReqCount;
                        return new Result(deleteReqCount, updateReqCount);
                    }
            ));
}

List<Operator> operatorList = Arrays.asList(
        new Operator("cricket", true, true),
        new Operator("cricket", true, false),
        new Operator("cricket", true, true),
        new Operator("soccer", false, true),
        new Operator("soccer", true, true)
);
System.out.println(solve(operatorList));

输出:

{soccer=Result{deleteReqCount=2, updateReqCount=1}, cricket=Result{deleteReqCount=2, updateReqCount=3}}

Sai Kiran 的精彩回答更新:

Map<String, Result> solve(List<Operator> operatorList) {
    return operatorList.stream()
        .collect(Collectors.toMap(
                v -> v.type,
                v -> new Result(v.deleteRequested ? 1 : 0, v.updateRequested ? 1 : 0),
                (result, result2) -> {
                    result.updateReqCount += result2.updateReqCount;
                    result.deleteReqCount += result2.deleteReqCount;
                    return result;
                }
        ));
}

当你更新到Java12或更高版本时,可以使用Collectors.teeing完成任务:

List<Operator> ops = //your operators list

Map<String, Result> myMap =          
    ops.stream()
       .collect(
            Collectors.groupingBy(Operator::getType,
                 Collectors.teeing(
                           Collectors.filtering(Operator::isUpdateRequested,Collectors.counting()),
                           Collectors.filtering(Operator::isDeleteRequested,Collectors.counting()),
                           (updateCount, deleteCount) -> {
                                return new Result(updateCount.intValue(),deleteCount.intValue());
                           }
               )));

根据@Andreas 的评论,

    operators.stream().collect(Collectors.toMap(
            Operator::getType,
            v -> new Result(v.isDeleteRequested() ? 1 : 0, v.isUpdateRequested() ? 1 : 0),
            Result::merge
    ));

合并方法,

  public Result merge(Result result) {
      this.updateReqCount+=result.updateReqCount;
      this.deleteReqCount+=result.deleteReqCount;
      
      return this;
  }