如何用Java8 Stream API找到心儀的女朋友


傳統的的Java 集合操作是有些啰嗦的,當我們需要對結合元素進行過濾,排序等操作的時候,通常需要寫好幾行代碼以及定義臨時變量。
而Java8 Stream API 可以極大簡化這一操作,代碼行數少,且易讀。

我們以“找女朋友”為例來看看Java8的Stream API相比傳統寫法有多香。假設我們定義了一個女朋友類,具有幾個關鍵的指標:姓名,身高,體重,顏值。如下所示:

class Girl {
    private String name;
    private int height;
    private int weight;
    private int score;
    // 省略get,set及hashCode等方法
}    

我們有一批適齡女青年名單,如下:

public static List<Girl> initGirlList(){
    List<Girl> result = new ArrayList<>();
    result.add(new Girl("趙小花",170,60,6));
    result.add(new Girl("錢小花",171,62,7));
    result.add(new Girl("孫小花",172,59,8));
    // 省略.... 
    return result;
}

心儀女朋友的篩選條件

假設心儀的女朋友是:體重,身高適中,顏值越高越好。本次設置的條件是找出:身高>=162 並且 體重<=53的女孩,然后按顏值排序前三名。

Java7的寫法

數據去重

由於數據可能有重復,這會干擾我們的篩選,因此,第一步先去掉重復數據。代碼如下:

List<Girl> girlList = initGirlList();// 初始化一批數據
// 數據去重
List<Girl> distinctGirl = new ArrayList<>();
for (Girl g: girlList){
    if(!distinctGirl.contains(g)){
        distinctGirl.add(g);
    }
}

這里new了一個新的distinctGirl來存放去重之后的數據,代碼很簡單,沒啥可說的。

篩選數據

下面我們要去掉不合格的數據,本次篩選條件是身高>=162 並且 體重<=53,代碼如下:

// 過濾身高,體重不符合的
List<Girl> girlTemp = new ArrayList<>();
for(Girl g: distinctGirl){
    if(g.getHeight() >= 162 && g.getWeight() <= 53){
        girlTemp.add(g);
    }
}

這里運用上一步中去重之后的distinctGirl,遍歷,並將符合條件的放入新的list girlTemp,這里又創建了一個中間list。

數據排序

經過上面啰嗦的兩步,我們得到了符合我們要求的數據,現在我們需要根據顏值高低進行排名,代碼如下:

Collections.sort(girlTemp, new Comparator<Girl>() {
    @Override
    public int compare(Girl g1, Girl g2) {
        BigDecimal score1 = new BigDecimal(g1.getScore());
        BigDecimal score2 = new BigDecimal(g2.getScore());
        return score2.subtract(score1).intValue();
    }
});

這里使用了Collections工具類的sort方法,傳遞了一個匿名類,並在其compare方法中實現了排序的邏輯,這依然是傳統集合排序的操作。

輸出結果

經過上面的幾步傳統的Java集合操作,我們終於得到了想要的數據。現在我們要輸出前三名。

int i = 1;
for (Girl g : girlTemp) {
    if(i>=3){
        break;
    }
    System.out.println(g.toString());
}

OK,至此我們的程序輸出了篩選的結果。上面的寫法,貌似邏輯很清晰,一步步徐徐漸進。是的,這種傳統的寫法,Java程序員們已經樂呵呵的寫了很多年了。
一看這個代碼足足有20多行!可是實現的邏輯並沒有太復雜啊?過陣子你回頭看這個代碼的話,你多半忘記了這么一大段代碼是干嘛的。如果有注釋還好,你大概掃一一眼能幫助你快速理清代碼做了啥。如果沒有注釋,你需要逐行去讀完這20多行代碼,才能明白其邏輯。

Java8 Stream API的寫法

這里我們在回顧一下,我們的目標:從一個girlList中找出:身高>=162 並且 體重<=53的女孩,然后按顏值排序前三名。Java8的代碼如下:

List<Girl> girlList = initGirlList();
girlList.stream()
        .filter( g -> g.getHeight() >= 162 && g.getWeight() <= 53)
        .distinct()
        .sorted(Comparator.comparing(Girl::getScore).reversed())
        .limit(3)
        .forEach( g -> System.out.println(g.toString()));

代碼6行!並且即使不了解Stream API,且你第一次看這個代碼也能猜出是什么意思,filter-過濾,distinct-去重,sort-排序,limit-限制條數,forEach-遍歷,就這么簡單。

結語

Java 這么老語言,如今都Java13了,然而,最具影響的版本我認為還是Java8。我上學那會兒,學校用Java6的寫法教學。工作之后開始寫Java7的try-with-resource、鑽石語法等。一直到現在,市面上很多項目都是Java7。有一次有同事給我說他在前公司寫Java8被項目經理說了一頓,我問為啥。他說因為項目經理認為寫Java7好維護,團隊人人都會寫Java7,寫Java8的人不多……無語凝噎。

如果你還沒用上Java8,但願本文中的小例子已經成功的勾起了你用上Java8的興致。問卷:你現在使用的版本是多少?
評論下面附了完整源碼

alt 逃離沙漠公眾號
推薦閱讀
Java8系列- 何用Java8 Stream API進行數據抽取與收集
SpringMVC是怎么工作的,SpringMVC的工作原理
Mybatis Mapper接口是如何找到實現類的-源碼分析
小程序雲開發:菜鳥也能全棧做產品
CORS詳解,CORS原理分析
工作6年,失業19天
Docker & k8s 系列一:快速上手docker
Docker & k8s 系列二:本機k8s環境搭建
Docker & k8s 系列三:在k8s中部署單個服務實例


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM