JavaRush /Java Blog /Random-TW /擺脫 Java 8 中的循環
KapChook
等級 19
Volga

擺脫 Java 8 中的循環

在 Random-TW 群組發布
Java 8 中引入的函數式風格是對該語言的一個重要補充。現在Java不再是純粹的OOP,而是OOP和函數式程式設計的混合體。這是一個遊戲規則的改變者,我們需要改變我們的 OOP 大腦來吸收這些變化。 消除 Java 8 中的循環 - 1但我們為什麼要接受這些改變呢?當我們可以用純 OOP 來解決問題時,為什麼還要浪費時間去嘗試函數式風格呢?
  • Java 8中引入的函數式風格幫助我們縮小了業務邏輯和程式碼之間的差距。它使我們能夠在更高層次上以自然流暢的方式講述故事。你可以說你想做什麼,而不是說你想怎麼做。

  • 程式碼變得更乾淨、更簡潔。

  • 高階函數使我們能夠:

    • 將函數傳送給其他函數
    • 在其他函數中建立函數
    • 從其他函數返回函數

    這對 Java 來說是一個巨大的勝利,我們需要發送、建立和傳回物件來執行此操作。我們將能夠編寫更可靠、更有針對性、更容易重複使用的程式碼。

  • 感謝 lambda,我們可以進行惰性計算。當 lambda 表達式作為方法參數發送時,編譯器將在方法中呼叫它時對其進行計算。這與立即評估的普通方法參數不同。

  • Lambda 讓編寫單元測試變得有趣。它們使我們能夠創建乾淨、尺寸小且編寫快速的輕量級測試。我們可以使用 lambda 來根除被測程式碼。這使我們能夠測試各種場景將如何影響程式碼。

  • 學習新模式。

  • 還有更多!

但是水夠了,在本文中我們將看看傳統循環的替代方案。當然,週期是靈活的,但這並不是沒有代價的。break,大大改變了循環的行為,迫使我們不僅要理解程式碼試圖實現的目標,continue還要return理解循環是如何運作的。現在我們將看看如何將循環轉換為更簡潔和可讀的程式碼。

讓編碼開始吧!

我們將使用文章。一篇文章有​​標題、作者和幾個標籤。
private class Article {

    private final String title;
    private final String author;
    private final List<String> tags;

    private Article(String title, String author, List<String> tags) {
        this.title = title;
        this.author = author;
        this.tags = tags;
    }

    public String getTitle() {
        return title;
    }

    public String getAuthor() {
        return author;
    }

    public List<String> getTags() {
        return tags;
    }
}
每個範例都將包含使用循環的傳統解決方案和使用 Java 8 新功能的解決方案。在第一個範例中,我們希望找到集合中帶有標籤「Java」的第一篇文章。讓我們來看看使用循環的解決方案。
public Article getFirstJavaArticle() {

    for (Article article : articles) {
        if (article.getTags().contains("Java")) {
            return article;
        }
    }
    return null;
}
現在讓我們使用 Stream API 中的操作來解決該問題。
public Optional<Article> getFirstJavaArticle() {
    return articles.stream()
        .filter(article -> article.getTags().contains("Java"))
        .findFirst();
    }
很酷,不是嗎?我們首先使用該操作filter來尋找所有帶有「Java」標籤的文章,然後使用該操作findFirst()來取得第一個出現的文章。由於流是惰性的並且過濾器返回流,因此這種方法只會處理元素,直到找到第一個匹配項。現在讓我們取得所有標記為「Java」的文章,而不僅僅是第一篇。首先是使用循環的解決方案。
public List<Article> getAllJavaArticles() {

    List<Article> result = new ArrayList<>();

    for (Article article : articles) {
        if (article.getTags().contains("Java")) {
            result.add(article);
        }
    }
    return result;
}
使用流操作的解決方案。
public List<Article> getAllJavaArticles() {
    return articles.stream()
        .filter(article -> article.getTags().contains("Java"))
        .collect(Collectors.toList());
    }
在此範例中,我們使用操作collect來縮短結果流,而不是聲明集合併明確新增符合的條目。到目前為止,一切都很好。是時候讓 Stream API 真正發揮作用的範例了。讓我們按作者將所有文章分組。像往常一樣,我們首先使用循環來解決它:
public Map<String, List<Article>> groupByAuthor() {

    Map<String, List<Article>> result = new HashMap<>();

    for (Article article : articles) {
        if (result.containsKey(article.getAuthor())) {
            result.get(article.getAuthor()).add(article);
        } else {
            ArrayList<Article> articles = new ArrayList<>();
            articles.add(article);
            result.put(article.getAuthor(), articles);
        }
    }
    return result;
}
我們可以使用流操作找到一個乾淨的解決方案來解決這個問題嗎?
public Map<String, List<Article>> groupByAuthor() {
    return articles.stream()
        .collect(Collectors.groupingBy(Article::getAuthor));
}
驚人的!透過使用操作groupingBy和方法引用getAuthor(),我們可以獲得乾淨且可讀的程式碼。現在讓我們找到集合中使用的其餘標籤。讓我們從一個循環範例開始:
public Set<String> getDistinctTags() {

    Set<String> result = new HashSet<>();

    for (Article article : articles) {
        result.addAll(article.getTags());
    }
    return result;
}
好吧,讓我們看看如何使用串流操作來解決這個問題:
public Set<String> getDistinctTags() {
    return articles.stream()
        .flatMap(article -> article.getTags().stream())
        .collect(Collectors.toSet());
}
涼爽的!flatmap幫助我們將標籤清單扁平化為單一結果流,然後我們用它collect來建立返回集。

無限可能

這些是如何用更具可讀性的程式碼替換循環的 4 個範例。請務必查看 Stream API,因為本文只觸及了表面。掌握 Java 新的函數式風格對於 OOP 開發人員來說將是一個挑戰,但這是一個應該受到廣泛歡迎的挑戰。我甚至會更進一步說,你應該學習一門純函數式程式語言。這樣您就可以充分了解它提供的功能和力量。我認為這將幫助您在不同層面上理解函數式程式設計。因此,學習函數式程式設計和古老的 OOP,並使用它們來編寫更出色的程式碼!兩篇文章的免費翻譯組合 -為什麼你應該擁抱 Java 8 中的函數式程式設計遠離 Java 8 中的循環
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION