Java詳細分析Lambda表達式與Stream流的使用方法
Lambda
Lambda 表達式是一個匿名函數(shù),我們可以把 lambda 表達式理解為一段可以傳遞的代碼(將代碼段像數(shù)據(jù)一樣傳遞)。使用它可以寫出更簡潔, 更靈活的代碼。作為一種更緊湊的代碼風格,使 java 語言的表達式能力得到的提升。
我們可以知道, Lambda表達式是為簡化語法而存在的
ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.sort(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o2.compareTo(o1);
}
});
System.out.println(list);這里有一個List集合 , 并添加了一些元素, 我們想對他進行排序, 并且按照降序的方式來排 , 在沒接觸Lambda表達式之前 ,我們是向上面那樣去做的
上面這種方式是匿名內(nèi)部類寫法 , 調用sort()方法時, 要求傳入一個比較器, Comparator是一個接口, 接口可以new嗎? 肯定是不能的 , 所以這里是有一個隱藏的類去實現(xiàn)了Comparator接口, 并且重寫了它里面的compare()方法 , 來制定我們的比較規(guī)則, 這個隱藏的類沒有類名, 就是我們這里所說的匿名內(nèi)部類 , 但方法也是不能作為參數(shù)去傳遞的, 所以我們new了這個匿名內(nèi)部類的對象 , 包裹了實現(xiàn)后的方法
但是現(xiàn)在我們嫌這個寫法太啰嗦了 ,我們使用Lambda來看看
// Lambda表達式
list.sort((o1,o2) -> {return o2.compareTo(o1);});這就和上面的匿名內(nèi)部類寫法是一樣的
Lambda表達式的結構 :
左側:lambda 表達式的參數(shù)列表
右側:lambda 表達式中需要執(zhí)行的功能,即 lambda 體
(arg1, arg2...) -> { body }
(type1 arg1, type2 arg2...) -> { body }
常見例子
無參數(shù),無返回值,lambda 體中只有一行代碼時,{}可以忽略 () -> System.out.println("Hello World");
無參數(shù),有返回值 () -> { return 3.1415 };
有參數(shù),無返回值 (String s) -> { System.out.println(s); }
有一個參數(shù),無返回值 s -> { System.out.println(s); }
有多個參數(shù),有返回值 (int a, int b) -> { return a + b; }
有多個參數(shù),表達式參數(shù)類型可以不寫,jvm 可以根據(jù)上下文進行類型推斷 (a, b) -> { return a - b; }
功能接口
功能接口上面一般會有這樣一個注解標簽@FunctionalInterface , 它表示此接口只有一個抽象方法, 當你注釋的接口違反了 Functional Interface 的契約時,它可以用于編譯器級錯誤
例如 : 我們剛使用的comparator接口就有這樣的注解

Stream流
允許你以聲明式的方式處理數(shù)據(jù)集合,可以把 它看作是遍歷數(shù)據(jù)集的高級迭代器。此外與 stream 與 lambada 表達示結合后 編碼效率與大大提高,并且可讀性更強。
流更偏向于數(shù)據(jù)處理和計算,比如 filter、map、find、sort 等。簡單來說,我們通過一個集合的 stream 方法獲取一個流,然后對流進行一 系列流操作,最后再構建成我們需要的數(shù)據(jù)集合。

我們常常將Stream流與Lambda表達式結合來編碼 , 那么如何來使用呢 ?
這里分為 3 步 :
1. 獲得流
2. 中間操作
3. 終端操作
中間操作(往往對數(shù)據(jù)進行篩選)
- filter:過濾流中的某些元素,
- sorted(): 自然排序,流中元素需實現(xiàn) Comparable 接口
- distinct: 去除重復元素
- limit(n): 獲取 n 個元素
- skip(n): 跳過 n 元素,配合 limit(n)可實現(xiàn)分頁
- map(): 將其映射成一個新的元素
終端操作(往往對結果集進行處理)
- forEach: 遍歷流中的元素
- toArray:將流中的元素倒入一個數(shù)組
- Min:返回流中元素最小值 Max:返回流中元素最大值
- count:返回流中元素的總個數(shù)
- Reduce:所有元素求和
- anyMatch:接收一個 Predicate 函數(shù),只要流中有一個元素滿足條件則返回 true,否則返回
- falseallMatch:接收一個 Predicate 函數(shù),當流中每個元素都符合條件時才返回 true,否則返回 false
- findFirst:返回流中第一個元素
- collect:將流中的元素倒入一個集合,Collection 或 Map
Integer[] arr = new Integer[]{1,4,3,2,5,5};
Arrays.stream(arr) //拿到流
.filter((a) -> {return a>3;}) //中間操作,過濾
.forEach((a) -> { //終端操作,遍歷
System.out.println(a);
});
Integer[] arr = new Integer[]{1,4,3,2,5,5};
Object[] objects = Arrays.stream(arr)
.sorted().distinct() //排序并去重
.toArray(); //轉數(shù)組
System.out.println(Arrays.toString(objects));
Integer[] arr = new Integer[]{1,4,3,2,5,5};
Integer max = Arrays.stream(arr).distinct()
.max(((o1, o2) -> { //去重返回最大值
return o1 - o2;
})).get(); //拿到這個值
//此處max為終端操作,返回的已經(jīng)不是流,而是一個OPtion的對象
//它里面有一個get()方法可以返回這個值
System.out.println(max);
Integer[] arr = new Integer[]{1,4,3,2,5,5};
long count = Arrays.stream(arr).distinct()
.count(); //返回總個數(shù)
System.out.println(count);
Integer[] arr = new Integer[]{1,4,3,2,5,5};
Integer i = Arrays.stream(arr).distinct()
.reduce((o1, o2) -> { //所有元素求和
return o1 + o2;
})
.get();
System.out.println(i);這里需要注意的是中間操作的map()方法和終端操作的collect()方法
設計一個Apple類
public class Apple {
private Integer num;
private String name;
private String color;
}并給出 構造 , set 和 get 方法 ,此處由于篇幅 原因省略
List<Apple> list = new ArrayList<>(); list.add(new Apple(100,"蘋果1","紅色")); list.add(new Apple(105,"蘋果5","紅色")); list.add(new Apple(104,"蘋果4","紅色")); list.add(new Apple(103,"蘋果3","紅色")); list.add(new Apple(102,"蘋果2","紅色"));
往一個list添加5個元素
List<String> collect = list.stream()
//將屬性的一列通過get方法映射成流
.map(Apple::getName)
//轉為一個list集合
.collect(Collectors.toList());
System.out.println(collect);
List<Apple> collect = list.stream().sorted(((o1, o2) -> {
//通過num屬性自定義排序
return o1.getNum() - o2.getNum();
}))
//轉為一個list集合
.collect(Collectors.toList());
System.out.println(collect);
Map<Integer, String> map = list.stream().sorted(((o1, o2) -> {
return o1.getNum() - o2.getNum();
}))
//轉map, 第一個參數(shù)為鍵,第二個參數(shù)為值
.collect(Collectors.toMap(Apple::getNum, Apple::getName));
System.out.println(map);到此關于Lambda表達式與Stream流就介紹完了,感謝閱讀
到此這篇關于Java詳細分析Lambda表達式與Stream流的使用方法的文章就介紹到這了,更多相關Java Lambda與Stream內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
- 一文帶你徹底了解Java8中的Lambda,函數(shù)式接口和Stream
- Java的Lambda表達式和Stream流的作用以及示例
- Java分析Lambda表達式Stream流合并分組內(nèi)對象數(shù)據(jù)合并
- Java中的lambda和stream實現(xiàn)排序
- 吊打Java面試官之Lambda表達式 Stream API
- Java8中Lambda表達式使用和Stream API詳解
- 詳解Java遞歸實現(xiàn)樹形結構的兩種方式
- Java實現(xiàn)樹形結構的示例代碼
- Java樹形結構數(shù)據(jù)生成導出excel文件方法記錄
- Java使用 Stream 流和 Lambda 組裝復雜父子樹形結構
相關文章
在SpringBoot當中使用Thymeleaf視圖解析器的詳細教程
Thymeleaf是一款開源的模板引擎,它允許前端開發(fā)者使用HTML與XML編寫動態(tài)網(wǎng)頁,hymeleaf的主要特點是將表達式語言嵌入到HTML結構中,它支持Spring框架,使得在Spring MVC應用中集成非常方便,本文給大家介紹了在SpringBoot當中使用Thymeleaf視圖解析器的詳細教程2024-09-09
徹底理解Spring注解@Autowired實現(xiàn)原理
這篇文章主要為大家詳細的介紹了Spring注解@Autowired實現(xiàn)的原理,縝密的邏輯分析,實踐應用示例操作說明,讓大家徹底的理解Spring注解@Autowired背后實現(xiàn)原理2022-03-03
Spring注解Autowired的底層實現(xiàn)原理詳解
從當前springboot的火熱程度來看,java?config的應用是越來越廣泛了,在使用java?config的過程當中,我們不可避免的會有各種各樣的注解打交道,其中,我們使用最多的注解應該就是@Autowired注解了。本文就來聊聊Autowired的底層實現(xiàn)原理2022-10-10

