java lambda collect_45分钟学会Java8 - Lambda和Stream
Java11已出,Java8已是主流。
現(xiàn)在來一波操作,應(yīng)該不會(huì)太遲(T_T)
注:本文持續(xù)更新 ^_^
1. 前言
本文主要介紹Java8的2大主要新特性lambda表達(dá)式和Stream API,2者提供了更高層次的抽象,簡(jiǎn)化開發(fā),提高生產(chǎn)效率。
2. Lambda表達(dá)式
2.1 初識(shí)Lambda表達(dá)式
創(chuàng)建一個(gè)線程,使用了一個(gè)Runnable匿名內(nèi)部類
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hello Aron.");
}
});
看著問題不大,實(shí)際上弊端挺明顯:模板語法太多,真正有業(yè)務(wù)意義的的語句只有System.out.println("Hello Aron."),因?yàn)槿绱?#xff0c;也嚴(yán)重干擾了我們閱讀代碼。
引入lambda表達(dá)式后,則可以這么寫
Thread thread = new Thread(() -> System.out.println("Hello Aron."));
簡(jiǎn)潔了太多,有木有?
2.2 更多Lambda表達(dá)式
Runnable runnable = () -> System.out.println("Hello World.");
Consumer tConsumer = bean -> System.out.println("Hello World.");
Runnable runnable1 = () -> {
System.out.println("Hello World.");
System.out.println("Hello World.");
};
語法分為3段式:參數(shù) 、-> 以及語句,即(...)-> { ...}
2.3 函數(shù)接口
Java是強(qiáng)類型語言,方法參數(shù)都有固定的類型。那么問題了,Lambda表達(dá)式,如果當(dāng)做是一堆代碼片段,也會(huì)表達(dá)一種明確的意圖,這個(gè)意圖,姑且可以理解為函數(shù)接口。
在編程過程中,總會(huì)遇到很多函數(shù)接口,以下是JDK中一些比較最重要的函數(shù)接口
接口參數(shù)返回類型示例
接口
參數(shù)
返回類型
示例
Predicate
T
boolean
值等于“Hello”嗎?
Consumer
T
void
輸出一個(gè)值
Function
T
R
獲取對(duì)象的一個(gè)屬性
Supplier
None
T
工廠方法
UnaryOperator
T
T
邏輯非(!)
BinaryOperator
(T, T)
T
求2個(gè)數(shù)的和(+)
2.4 類型推斷
先看一段熟悉的集合代碼
ArrayList list = new ArrayList<>();
在ArrayList中申明了存儲(chǔ)的元素的類型,于是在ArrayList<>()這里的類型可以缺省,編譯器可以根據(jù)左側(cè)(即上文)推斷出來。
同理,在lambda表達(dá)式也是一樣的。
BinaryOperator addLongs = (x, y) -> x + y;
在上面的表達(dá) 式中,我們注意到 (x, y)這里是沒有申明方法的參數(shù)類型的,卻能執(zhí)行數(shù)學(xué)運(yùn)算 +。
這里根據(jù)函數(shù)接口指定的泛型類為L(zhǎng)ong,即可推斷方法的參數(shù)為L(zhǎng)ong,然后執(zhí)行x + y。
2.5 Lambda小結(jié)
Lambda表達(dá)式是一個(gè)匿名方法,簡(jiǎn)化了匿名內(nèi)部類的寫法,把模板語法屏蔽,突出業(yè)務(wù)語句,傳達(dá)的更像一種行為。
Lambda表達(dá)式是有類型的,JDK內(nèi)置了眾多函數(shù)接口
Lambda的3段式結(jié)構(gòu):(...)-> { ...}
3. Stream 流
3.1 簡(jiǎn)介
流(Stream)是Java8的新特性,是一種使程序員得以站在更高的抽象層次上對(duì)集合進(jìn)行操作。在思路上,類似于SQL的存儲(chǔ)過程,有幾個(gè)步驟:
先定義一些操作的集合,注意:這里只定義,不真正執(zhí)行
觸發(fā)執(zhí)行,獲取結(jié)果
對(duì)結(jié)果進(jìn)一步處理,篩選、打印、使用
其中,第1步的定義操作叫惰性求值,給你套路(返回Stream),但是不會(huì)執(zhí)行返回結(jié)果。
第2步的觸發(fā)操作叫及早求值,這個(gè)人說干就干,立馬要結(jié)果(返回結(jié)果數(shù)據(jù))。
第3步的篩選類似SQL的where子句,對(duì)結(jié)果進(jìn)一步的篩選。
3.2 Stream API
Stream 類位于java.util.stream包,是Java8核心的類之一,擁有眾多方法,下面羅列了一些比較重要的方法進(jìn)行講解。更多的是拋磚引玉,任何教程都比不上自己的悟性來得爽快,先找點(diǎn)感覺,先掌握基本用法嘗試使用起來,慢慢自然就會(huì)了。
3.2.1 Stream.of(T… t)
要使用Stream,那就必須得先創(chuàng)建一個(gè)String類型的Stream
Stream StrStream = Stream.of("a", "b");
3.2.2 Stream.collect(Collector super T, A, R> collector)
使用收集器Collector將StrStream轉(zhuǎn)化為熟悉的集合Collection
List collect = StrStream.collect(Collectors.toList());
3.2.2 Stream.map(Function super T, ? extends R> mapper)
所謂map,從字面理解就是映射。這里指的是對(duì)象關(guān)系的映射,
比如從對(duì)象集合映射到屬性結(jié)合:
List names = Stream.of(new Student("zhangSan"), new Student("liSi"))
.map(student -> student.getName())
.collect(toList());
從小寫字母映射到大寫字母:
List collected = Stream.of("a", "b", "hello")
.map(string -> string.toUpperCase())
.collect(toList());
將 字符串流 根據(jù)空格分割成 字符串?dāng)?shù)組流
Stream stringStream = Stream.of("Hello Aron.");
Stream stringArrayStream = stringStream.map(word -> word.split(" "));
3.2.3 Stream.filter(Predicate super T> predicate)
filter顧名思義,過濾篩選。這里的參數(shù)函數(shù)接口是一個(gè)條件,篩選出滿足條件的元素
// 篩選年齡大于19的學(xué)生
List stu = Stream.of(new Student("zhangSan", 19), new Student("liSi"), 20)
.filter(student -> student.getAge() > 19)
.collect(toList());
3.2.4 Stream.flatMap(Function super T, ? extends Stream extends R>> mapper)
flatMap扁平化映射,即將數(shù)據(jù)元素為數(shù)組的Stream轉(zhuǎn)化為單個(gè)元素
Stream stringStream = Stream.of("Hello Aron.");
// 返回值為數(shù)組
Stream stringArrayStream = stringStream.map(word -> word.split(" "));
// flatMap扁平化映射后,元素都合并了
Stream flatResult = stringArrayStream.flatMap(arr -> Arrays.stream(arr))
3.2.5 Stream.max(Comparator super T> comparator)
max即最大,類似SQL中的函數(shù)max(),從數(shù)據(jù)中根據(jù)一定的條件篩選出最值
// 篩選年齡最大/小的學(xué)生
Stream studentStream = Stream.of(new Student("zhangSam", 19), new Student("liSi", 20));
Optional max = studentStream.max(Comparator.comparing(student -> student.getAge()));
// Optional max = studentStream.min(Comparator.comparing(student -> student.getAge()));
// 年齡最大/小的學(xué)生
Student student = max.get();
3.2.7 Sream.reduce(T identity, BinaryOperator binaryOperator)
reduce操作實(shí)現(xiàn)從一組值中生成一個(gè)值,上面的max、min實(shí)際上都是reduce操作。
參數(shù)Identity 表示初始值,
參數(shù)binaryOperator是一個(gè)函數(shù)接口,表示二元操作,可用于數(shù)學(xué)運(yùn)算
// 使用reduce() 求和 (不推薦生產(chǎn)環(huán)境使用)
int count = Stream.of(1, 2, 3).reduce(0, (acc, element) -> acc + element);
上面代碼,展開reduce() 操作
BinaryOperator accumulator = (acc, element) -> acc + element;
int count = accumulator.apply( accumulator.apply(accumulator.apply(0, 1),2), 3);
3.2.8 綜合操作
// 查找所有姓張的同學(xué)并按字典順序排序,存儲(chǔ)到list
List newList = studentList.Stream()
.filter(student -> student.getName().startsWith("張"))
.sorted(Comparator.comparing(student -> student.getName())
.collect(toList());
覺得有用,記得收藏、點(diǎn)贊哦!
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的java lambda collect_45分钟学会Java8 - Lambda和Stream的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: kotlin 反射java类_关于Kot
- 下一篇: java master work_并发编