簡體   English   中英

使用 Streams 替換循環

[英]Using Streams to replace loops

我有以下代碼:

boolean found = false;
for (Commit commit : commits.values()) {
    if (commit.getLogMessage().compareTo(commitMessageToSearch) == 0) {
        System.out.println(commit.getSha());
        found = true;
    }
}
if (!found) {
    System.out.println("aksdhlkasj");
}

有什么方法可以簡潔地使用流或 Java 中的其他任何東西來編寫這個

您可以將Stream#filterStream#findFirst一起使用。

System.out.println(commits.values().stream()
    .filter(commit -> commit.getLogMessage().compareTo(commitMessageToSearch) == 0)
    .findFirst().map(Commit::getSha).orElse("aksdhlkasj"));

只需使用 lambda 表達式用 stream 功能替換您的邏輯

    boolean found = false;
    
    commits.values().stream().filter(c -> 
    c.getLogMessage().compareTo(commitMessageToSearch) == 0).forEach(c -> {
    System.out.println(c.getSha());
    found = true;
    });
    
    if (!found) {
        System.out.println("aksdhlkasj");
    }

由於需要在循環外檢查“狀態”,因此使用Stream::forEach的基於流的解決方案將在 stream 之外設置found的值,因此不是純的,但它會將所有過濾的 SHA 代碼打印為for-loop版本:

AtomicBoolean found = new AtomicBoolean(); // effectively final container boolean

commits.values().stream()
    .filter(commit -> commit.getLogMessage().compareTo(commitMessageToSearch) == 0)
    .map(Commit::getSha)
    .forEach(sha -> {
        found.set(true); 
        System.out.println(sha);
    });

if (!found.get()) {
    System.out.println("none found");
}

或者使用短路Stream::anyMatch來檢查過濾后的 stream 是否包含至少一個匹配條目:

if (commits.values().stream()
    .map(Commit::getLogMessage) // equals should be equivalent to compareTo == 0
    .anyMatch(commitMessageToSearch::equals))
{
    commits.values().stream()
        .filter(commit -> commit.getLogMessage().compareTo(commitMessageToSearch) == 0)
        .map(Commit::getSha)
        .forEach(System.out::println);
} else {
    System.out.println("none found");
}

但這絕對比for-loop解決方案更冗長。

你要這個:

commits.values()
       .stream()
       .filter(commit -> commit.getLogMessage().compareTo(commitMessageToSearch) == 0)
       .findFirst()
       .map(Commit::getSha)
       .ifPresentOrElse(
               System.out::println,                      // if present, print out sha
               () -> System.out.println("aksdhlkasj"));  // print some garbage otherwise

基本上,您過濾掉不需要的提交。 一旦找到正確的,只要不需要進一步搜索,方法Stream#findfirst就會使處理短路。 因此,您可能希望在 for 循環中添加break 最后,使用Optional#mapCommit中提取sha ,然后Optional#ifPresentOrElse處理這兩種情況,無論是否存在此類提交。

暫無
暫無

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

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