簡體   English   中英

布爾值流,是真的嗎?

[英]Stream of boolean values, is any true?

我想並行化使用parallelStream截取的以下代碼:

boolean anyTrue() {
  for (Element e : setOfE) {
    if (eval(e)) {
      return true;
    }
  }
  return false;
}

以下是否適用於並行流並使用常規短路評估?

setOfE.parallelStream().map(e -> eval(e)).reduce(false, (a,b) -> a || b))

Streams API 實際上為您的需求提供一流的支持:

setOfE.parallelStream().anyMatch(e->eval(e));

與您使用reduce的方法相反,這可以保證進行短路評估並最佳地利用並行性。

不,減少不支持短路評估。 原因是reduce只接收任意的BinaryOperator實現,並且不知道短路特定操作的可能性。

但是您可以更簡單地執行整個操作:

setOfE.parallelStream().filter(e -> eval(e)).findAny().isPresent()

這只是搜索eval返回true的任意項目,並且findAny允許在一個線程遇到匹配時立即結束操作。 由於您對特定匹配的Element不感興趣,因此可以查詢結果Optional是否為空。

或者,您可以按照 Marko Topolnik 評論的建議使用:

setOfE.parallelStream().anyMatch(e -> eval(e))

我在那里,我不想短路我操作的情況。

我需要處理我所有的值,那么流的最終結果應該是一個anyMatch ,基本上。 但我實際上不能使用anyMatch ,因為一旦找到true值,它就會短路。

// WRONG for my case - need to process ALL field IDs
return fieldIs.stream()
        .map(UUID::toString)
        .anyMatch(fieldId -> processProjectForField(portfolioId, fieldId, projectId, fieldValueDataMap));

// RIGHT for my case - goes through all field IDs, and returns TRUE 
// if there is at least one 'true' return from the processProjectForField method.
return fieldIs.stream()
        .map(UUID::toString)
        .map(fieldId -> processProjectForField(portfolioId, fieldId, projectId, fieldValueDataMap))
        .reduce(Boolean.FALSE, Boolean::logicalOr);

// What you wrote is also acceptable
[...]
.reduce(false, (a,b) -> a || b));

// Another way of doing it 
[...]
.collect(Collectors.reducing(Boolean.FALSE, Boolean::logicalOr));]

更多靈感在這里。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM