天天看點

如何用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的興緻。問卷:你現在使用的版本是多少?

評論下面附了完整源碼

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

推薦閱讀

Java8系列- 何用Java8 Stream API進行資料抽取與收集

SpringMVC是怎麼工作的,SpringMVC的工作原理

Mybatis Mapper接口是如何找到實作類的-源碼分析

小程式雲開發:菜鳥也能全棧做産品

CORS詳解,CORS原理分析

工作6年,失業19天

Docker & k8s 系列一:快速上手docker

Docker & k8s 系列二:本機k8s環境搭建

Docker & k8s 系列三:在k8s中部署單個服務執行個體

感謝您的閱讀,歡迎您評論交流。PS:部落格園已停更,後續請通過郵件或者公衆号聯系