使用Java Streams递增和初始化多个计数器。

huangapple go评论72阅读模式
英文:

Incrementing and initializing multiple counters using Java Streams

问题

以下是使用流来初始化计数器并循环遍历集合的代码片段:

// 使用流来初始化计数器并循环遍历集合
int errorOnlyCount = (int) summaryReportItemList.stream()
        .map(this::getTermErrorCount)
        .filter(map -> map.get("errorCount") > 0 && map.get("warningCount") == 0)
        .count();

int warningOnlyCount = (int) summaryReportItemList.stream()
        .map(this::getTermErrorCount)
        .filter(map -> map.get("errorCount") == 0 && map.get("warningCount") > 0)
        .count();

int bothErrorAndWarningCount = (int) summaryReportItemList.stream()
        .map(this::getTermErrorCount)
        .filter(map -> map.get("errorCount") > 0 && map.get("warningCount") > 0)
        .count();

int successfulProcessedCount = (int) summaryReportItemList.stream()
        .map(this::getTermErrorCount)
        .filter(map -> map.get("errorCount") == 0 && map.get("warningCount") == 0)
        .count();

你可以根据这个模式,为每个计数器创建一个类似的流,然后使用 .count() 方法来获取满足条件的元素数量。这个代码片段会执行相同的操作,但是使用了流的方式,更加紧凑和函数式。记得在类中定义 getTermErrorCount 方法,它接收一个 ReportItem 对象并返回一个包含错误和警告计数的映射。

英文:

Please I need help with the use of streams to initialize counters while looping through a collection:

//Method containing the logic to be converted to streams

    int errorOnlyCount = 0;
    int warningOnlyCount = 0;
    int bothErrorAndWarningCount = 0;
    int successfulProcessedCount = 0;


for(ReportItem summaryReportItem: summaryReportItemList){
    Map<String, Integer> summaryReportItemMap = getTermErrorCount(summaryReportItem);

    if(summaryReportItemMap.get("errorCount").intValue() > 0 &&
            summaryReportItemMap.get("warningCount").intValue() == 0
    ){
        errorOnlyCount += 1;
    }

    if(summaryReportItemMap.get("errorCount").intValue() == 0 &&
            summaryReportItemMap.get("warningCount").intValue() > 0
    ){
        warningOnlyCount += 1;
    }

    if(summaryReportItemMap.get("errorCount").intValue() > 0 &&
            summaryReportItemMap.get("warningCount").intValue() > 0
    ){
        bothErrorAndWarningCount += 1;
    }

    if(summaryReportItemMap.get("errorCount").intValue() == 0 &&
            summaryReportItemMap.get("warningCount").intValue() == 0
    ){
        successfulProcessedCount += 1;
    }
}


//Method called from the logic above

private Map<String, Integer> getTermErrorCount(ReportItem summaryReportItem){
        int errorCount = 0;
        int warningCount = 0;

        if(summaryReportItem.getIsDuplicateItemError())
            errorCount += 1;
 
        if(summaryReportItem.getIsDescriptionWarning())
            warningCount += 1;

        Map<String, Integer> errorWarningCounterMap = new HashMap<>();
        errorWarningCounterMap.put("errorCount", errorCount);
        errorWarningCounterMap.put("warningCount", warningCount);

        return errorWarningCounterMap;
    }

//POJO with the string id and booleans variables

public class ReportItem {
        private String id;
        private boolean isMissingIdError;

        public ReportItem id(String id) {
            this.id = id;
            return this;
        }

        @Nonnull
        @JsonProperty("id")
        @JsonInclude(JsonInclude.Include.USE_DEFAULTS)
        public String getId() {
            return this.id;
        }

        public void setId(String id) {
            this.id = id;
        }

        public ReportItem isMissingIdError(Boolean isMissingIdError) {
            this.isMissingIdError = isMissingIdError;
            return this;
        }

    @Nullable
    @JsonProperty("isMissingIdError")
    @JsonInclude(JsonInclude.Include.USE_DEFAULTS)
    public Boolean getIsMissingIdError() {
        return this.isMissingIdError;
    }

    public void setIsMissingIdError(String id) {
        this.isMissingIdError = isMissingIdError;
    }
}

I was thinking of creating a stream for each if-block, but then how do I increment and initialize the counters.

Below is my code for the first counter's block.

 Stream<ReportItem> errorOnlyCountStream = summaryReportItemList.stream().filter(i -> (getTermErrorCount(i).get("errorCount").intValue() > 0 &&
                getTermErrorCount(i).get("warningCount").intValue() == 0));

Please, can someone help out with a snippet for the best approach?

答案1

得分: 2

你实际上可以从一个流中很好地完成所有这些操作。

Map<Boolean, Map<Boolean, Long>> results =
   summaryReportItemList.stream()
     .map(ThisClass::getTermErrorCount)
     .collect(
       Collectors.partitioningBy(
         map -> map.get("errorCount") > 0,
         Collectors.partitioningBy(
           map -> map.get("warningCount") > 0,
           Collectors.counting())));
int errorOnlyCount = results.get(true).get(false).intValue();
int warningOnlyCount = results.get(false).get(true).intValue();
int bothErrorAndWarningCount = results.get(true).get(true).intValue();
int successfullyProcessedCount = results.get(false).get(false).intValue();

从这段代码的特定结构来看,似乎你可以完全消除映射转换,并直接在 getIsDuplicateItemErrorgetIsDescriptionWarning 上进行分区,但这与你已经编写的代码最为相似。

英文:

You can actually do this all reasonably well from one stream.

Map&lt;Boolean, Map&lt;Boolean, Long&gt;&gt; results =
   summaryReportItemList.stream()
     .map(ThisClass::getTermErrorCount)
     .collect(
       Collectors.partitioningBy(
         map -&gt; map.get(&quot;errorCount&quot;) &gt; 0,
         Collectors.partitioningBy(
           map -&gt; map.get(&quot;warningCount&quot;) &gt; 0,
           Collectors.counting())));
int errorOnlyCount = results.get(true).get(false).intValue();
int warningOnlyCount = results.get(false).get(true).intValue();
int bothErrorAndWarningCount = results.get(true).get(true).intValue();
int successfullyProcessedCount = results.get(false).get(false).intValue();

From the particular structure of this code, it looks like you could eliminate the map conversion entirely and partition directly on getIsDuplicateItemError and getIsDescriptionWarning, but this is most similar to the code you've already written.

huangapple
  • 本文由 发表于 2020年10月15日 02:49:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/64359734.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定