自從Java8出現(xiàn)以來(lái)症脂,受到開發(fā)者青睞的要屬它的Lambda表達(dá)式啦皇型。Lambda表達(dá)式的出現(xiàn)默垄,有兩大明顯的優(yōu)點(diǎn):一是程序員開發(fā)的代碼量大大減少;二是由于Lambda表達(dá)式本身新的特性會(huì)使代碼的運(yùn)行效率大幅度提升巫湘。
Lambda表達(dá)式特性
- 代碼量減少
- 運(yùn)行效率提高
- 代碼可讀性提升
- 強(qiáng)大的Stream API(對(duì)集合對(duì)象進(jìn)行各種串行或并發(fā)聚集操作)
- 并行性
Lambda語(yǔ)法
1. 基本語(yǔ)法
(parameters) -> expression 或 (parameters) ->{ statements; }
即: 參數(shù) -> 帶返回值的表達(dá)式/無(wú)返回值的陳述
- 接收2個(gè)int型整數(shù),返回他們的和
(int x, int y) -> x + y; - 接受一個(gè) string 對(duì)象,并在控制臺(tái)打印,不返回任何值(看起來(lái)像是返回void)
(String s) -> System.out.print(s); - 當(dāng)方法不修改lambda表達(dá)式提供的參數(shù)時(shí)装悲,Lambda表達(dá)式內(nèi)可以使用方法引用
list.forEach(n -> System.out.println(n));
list.forEach(System.out::println); // 使用方法引用,見(jiàn)符號(hào)::
2.語(yǔ)法詳解
根據(jù)上面的描述尚氛,我們可以簡(jiǎn)單的抽象一下Lambda表達(dá)式的一般語(yǔ)法:
(Type1 param1, Type2 param2, ..., TypeN paramN) -> {
statment1;
statment2;
//.............
return statmentM;
}
// 對(duì)一個(gè)字符串列表诀诊,將字符串包含的字符串都轉(zhuǎn)換為小寫
List<String> lowercaseNames = names.stream().map((String name) -> {return name.toLowerCase();}).collect(Collectors.toList());
根據(jù)上面的語(yǔ)義,可以將Lambda表達(dá)式簡(jiǎn)單的理解為“一段帶有參數(shù)的可執(zhí)行語(yǔ)句塊”阅嘶。
上面的Lambda表達(dá)式語(yǔ)法可以認(rèn)為是最全的版本属瓣,寫起來(lái)還是稍稍有些繁瑣。別著急讯柔,下面陸續(xù)介紹一下Lambda表達(dá)式的各種簡(jiǎn)化版:
- 參數(shù)類型省略–絕大多數(shù)情況抡蛙,編譯器都可以從上下文環(huán)境中推斷出Lambda表達(dá)式的參數(shù)類型。這樣Lambda表達(dá)式就變成了:
(param1,param2, ..., paramN) -> {
statment1;
statment2;
//.............
return statmentM;
}
List<String> lowercaseNames = names.stream().map((name) -> {return name.toLowerCase();}).collect(Collectors.toList());
- 當(dāng)Lambda表達(dá)式的參數(shù)個(gè)數(shù)只有一個(gè)魂迄,可以省略小括號(hào)粗截。Lambda表達(dá)式簡(jiǎn)寫為:
param1 -> {
statment1;
statment2;
//.............
return statmentM;
}
List<String> lowercaseNames = names.stream().map(name -> {return name.toLowerCase();}).collect(Collectors.toList());
- 當(dāng)Lambda表達(dá)式只包含一條語(yǔ)句時(shí),可以省略大括號(hào)捣炬、return和語(yǔ)句結(jié)尾的分號(hào)熊昌。Lambda表達(dá)式簡(jiǎn)化為:
param1 -> statment
List<String> lowercaseNames = names.stream().map(name -> name.toLowerCase()).collect(Collectors.toList());
- 使用方法引用,如下:
List<String> lowercaseNames = names.stream().map(String::toLowerCase).collect(Collectors.toList());
stream API簡(jiǎn)單介紹
1.什么是stream
簡(jiǎn)單而言湿酸,stream就是JAVA8提供的對(duì)于元素集合統(tǒng)一婿屹、快速、并行的一種方法推溃。它能充分運(yùn)用多核的優(yōu)勢(shì)昂利,以及配合lambda表達(dá)式、鏈?zhǔn)浇Y(jié)構(gòu)對(duì)集合等進(jìn)行許多有用的操作铁坎。
概念:
可以支持順序和并行對(duì)原始操作的元素集合蜂奸。
作用:
提供了一種操作[大數(shù)據(jù)]接口,讓數(shù)據(jù)操作更容易和更快使用stream硬萍,從而能夠?qū)ollection的元素進(jìn)行過(guò)濾扩所、映射、排序襟铭、去重等許多操作。
中間方法和終點(diǎn)方法:
它具有過(guò)濾、映射以及減少遍歷數(shù)等方法寒砖,這些方法分兩種:中間方法和終端方法赐劣。
“流”抽象天生就該是持續(xù)的,中間方法永遠(yuǎn)返回的是stream哩都,因此如果我們要獲取最終結(jié)果的話魁兼,必須使用終點(diǎn)操作才能收集流產(chǎn)生的最終結(jié)果。區(qū)分這兩個(gè)方法是看他的返回值漠嵌,如果是stream則是中間方法咐汞,否則是終點(diǎn)方法。
2.如何使用stream
- 通過(guò)Stream接口的靜態(tài)工廠方法(注意:Java8里接口可以帶靜態(tài)方法)儒鹿;
- 通過(guò)Collection接口的默認(rèn)方法(默認(rèn)方法:Default method化撕,也是Java8中的一個(gè)新特性,就是接口中的一個(gè)帶有實(shí)現(xiàn)的方法)–stream()约炎,把一個(gè)Collection對(duì)象轉(zhuǎn)換成Stream植阴。
一般情況下,我們都使用Collection接口的 .stream()方法得到stream圾浅。
3.常見(jiàn)的中間方法
中間方法即是對(duì)元素進(jìn)行的操作掠手,例如過(guò)濾、去重狸捕、轉(zhuǎn)換喷鸽、截取等。
- 過(guò)濾 filter
//過(guò)濾18歲以上的人
List persons = …
//注意灸拍!此處返回的是Stream
Stream personsOver18 = persons.stream().filter(p -> p.getAge() > 18);
- 轉(zhuǎn)換 map
//把person轉(zhuǎn)成Adult
Stream map = persons.stream().filter(p -> p.getAge() > 18).map(person -> new Adult(person));
- 去重 distinct
- 截取 limit
4.常見(jiàn)的終點(diǎn)方法
通過(guò)中間方法做祝,我們對(duì)stream進(jìn)行了一系列的操作,但得到的還是一個(gè)stream株搔。要是想把它轉(zhuǎn)為新的集合或者是統(tǒng)計(jì)結(jié)果剖淀,我們需要使用終點(diǎn)方法。
- 統(tǒng)計(jì) count
count方法是一個(gè)流的終點(diǎn)方法纤房,可使流的結(jié)果最終統(tǒng)計(jì)纵隔,返回int,比如我們計(jì)算一下滿足18歲的總?cè)藬?shù)
int countOfAdult=persons.stream().filter(p -> p.getAge() > 18)
.map(person -> new Adult(person))
.count();
- 收集流的結(jié)果 collect
collect方法也是一個(gè)流的終點(diǎn)方法炮姨,可收集最終的結(jié)果
List adultList= persons.stream().filter(p -> p.getAge() > 18)
.map(person -> new Adult(person))
.collect(Collectors.toList());