傳統的的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系列- 何用Java8 Stream API進行資料抽取與收集
SpringMVC是怎麼工作的,SpringMVC的工作原理
Mybatis Mapper接口是如何找到實作類的-源碼分析
小程式雲開發:菜鳥也能全棧做産品
CORS詳解,CORS原理分析
工作6年,失業19天
Docker & k8s 系列一:快速上手docker
Docker & k8s 系列二:本機k8s環境搭建
Docker & k8s 系列三:在k8s中部署單個服務執行個體
感謝您的閱讀,歡迎您評論交流。PS:部落格園已停更,後續請通過郵件或者公衆号聯系