你還在Java8中使用迴圈語句嗎?

java邵先生發表於2018-09-11

Java 8中的新功能特性改變了遊戲規則。對Java開發者來說這是一個全新的世界,並且是時候去適應它了。

在這篇文章裡,我們將會去了解傳統迴圈的一些替代方案。在Java 8的新功能特性中,最棒的特性就是允許我們去表達我們想要完成什麼,而不是要怎樣做。這正是迴圈的不足之處。要確保迴圈的靈活性是需要付出代價的。return、break 或者 continue都會顯著地改變迴圈的實際表現。這迫使我們不僅要清楚我們要實現怎樣的程式碼,還要了解迴圈是怎樣工作的。

現在我們看看怎樣把這些迴圈轉換為更簡潔,可讀性更高的程式碼。

程式碼轉換

好吧,講的夠多了,是時候展示一些例子了!

這次我們要以文章為例子。一篇文章擁有一個標題,一個作者和幾個標籤。

private class Article {

    private final String title;

    private final String author;

    private final List tags;

    private Article(String title, String author, List tags) {

        this.title = title;

        this.author = author;

        this.tags = tags;

    }

    public String getTitle() {

        return title;

    }

    public String getAuthor() {

        return author;

    }

    public List getTags() {

        return tags;

    }

}

每個例子都會包含一個使用傳統迴圈的方案和一個使用Java 8新特性的方案。

在第一個例子裡,我們要在集合中查詢包含“Java”標籤的第一篇文章。

看一下使用for迴圈的解決方案。

public Article getFirstJavaArticle() {

    for (Article article : articles) {

        if (article.getTags().contains(“Java”)) {

            return article;

        }

    }

    return null;

}

現在我們使用Stream API的相關操作來解決這個問題。

public Optional getFirstJavaArticle() {  

return articles.stream()

    .filter(article -> article.getTags().contains(“Java”))

    .findFirst();

}

是不是很酷?我們首先使用 filter 操作去找到所有包含Java標籤的文章,然後使用 findFirst() 操作去獲取第一次出現的文章。因為Stream是“延遲計算”(lazy)的並且filter返回一個流物件,所以這個方法僅在找到第一個匹配元素時才會處理元素。

現在,讓我們獲取所有匹配的元素而不是僅獲取第一個。

首先使用for迴圈方案。

public List getAllJavaArticles() {

    List result = new ArrayList<>();

    for (Article article : articles) {

        if (article.getTags().contains(“Java”)) {

            result.add(article);

        }

    }

    return result;

}

使用Stream操作的方案。

public List getAllJavaArticles() {  

    return articles.stream()

        .filter(article -> article.getTags().contains(“Java”))

        .collect(Collectors.toList());

    }

在這個例子裡我們使用 collection 操作在返回流上執行少量程式碼而不是手動宣告一個集合並顯式地新增匹配的文章到集合裡。

到目前為止還不錯。是時候舉一些突出Stream API強大的例子了。

根據作者來把所有的文章分組。

照舊,我們使用迴圈方案。

public Map> groupByAuthor() {

    Map> result = new HashMap<>();

    for (Article article : articles) {

        if (result.containsKey(article.getAuthor())) {

            result.get(article.getAuthor()).add(article);

        } else {

            ArrayList articles = new ArrayList<>();

            articles.add(article);

            result.put(article.getAuthor(), articles);

        }

    }

    return result;

}

我們能否找到一個使用流操作的簡潔方案來解決這個問題?

public Map> groupByAuthor() {  

    return articles.stream()

        .collect(Collectors.groupingBy(Article::getAuthor));

}

很好!使用 groupingBy 操作和 getAuthor 方法,我們得到了更簡潔、可讀性更高的程式碼。

現在,我們查詢集合中所有不同的標籤。

我們從使用迴圈的例子開始。

public Set getDistinctTags() {

    Set result = new HashSet<>();

    for (Article article : articles) {

        result.addAll(article.getTags());

    }

    return result;

}

好,我們來看看如何使用Stream操作來解決這個問題。

public Set getDistinctTags() {  

    return articles.stream()

        .flatMap(article -> article.getTags().stream())

        .collect(Collectors.toSet());

}

棒極了!flatmap 幫我把標籤列表轉為一個返回流,然後我們使用 collect 建立了一個集合作為返回值。

以上的就是如何使用可讀性更高的程式碼代替迴圈的例子。很高興您能夠用心讀完,希望對您有所幫助。

Java高架構師、分散式架構、高可擴充套件、高效能、高併發、效能優化、Spring boot、Redis、ActiveMQ、Nginx、Mycat、Netty、Jvm大型分散式專案實戰學習架構師視訊免費學習加群:835638062 點選連結加入群聊【Java高階架構】:https://jq.qq.com/?_wv=1027&k=5S3kL3v


相關文章