真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Java之Lambda表達(dá)式使用

簡介
Lambda表達(dá)式(也稱閉包),是Java8中最受期待和歡迎的新特性之一。在Java語法層面Lambda表達(dá)式允許函數(shù)作為一個(gè)方法的參數(shù)(函數(shù)作為參數(shù)傳遞到方法中),或者把代碼看成數(shù)據(jù)。Lambda表達(dá)式可以簡化函數(shù)式接口的使用。函數(shù)式接口就是一個(gè)只具有一個(gè)抽象方法的普通接口,像這樣的接口就可以使用Lambda表達(dá)式來簡化代碼的編寫。
使用Lambda表達(dá)式的前提
對(duì)應(yīng)接口有且只有一個(gè)抽象方法?。。?br/>基礎(chǔ)語法
Lambda 表達(dá)式的基礎(chǔ)語法:Java8中引入了一個(gè)新的操作符 “->” 該操作符稱為箭頭操作符或 Lambda 操作符
箭頭操作符將 Lambda 表達(dá)式拆分成兩部分:
左側(cè):Lambda 表達(dá)式的參數(shù)列表
右側(cè):Lambda 表達(dá)式中所需執(zhí)行的功能, 即 Lambda 體
(args1, args2...) -> {};Lambda表達(dá)式的重要特征
可選類型聲明:不需要AxiTrader返傭www.kaifx.cn/broker/axitrader.html聲明參數(shù)類型,編譯器可以統(tǒng)一識(shí)別參數(shù)值。
可選的參數(shù)圓括號(hào):一個(gè)參數(shù)無需定義圓括號(hào),但多個(gè)參數(shù)需要定義圓括號(hào)。
可選的大括號(hào):如果主體包含了一個(gè)語句,就不需要使用大括號(hào)。
可選的返回關(guān)鍵字:如果主體只有一個(gè)表達(dá)式返回值則編譯器會(huì)自動(dòng)返回值,大括號(hào)需要指定明表達(dá)式返回了一個(gè)數(shù)值。
使用Lambda表達(dá)式的優(yōu)缺點(diǎn)
優(yōu)點(diǎn)
使用Lambda表達(dá)式可以簡化接口匿名內(nèi)部類的使用,可以減少類文件的生成,可能是未來編程的一種趨勢。
缺點(diǎn)
使用Lambda表達(dá)式會(huì)減弱代碼的可讀性,而且Lambda表達(dá)式的使用局限性比較強(qiáng),只能適用于接口只有一個(gè)抽象方法時(shí)使用,不宜調(diào)試。
函數(shù)式接口
只有函數(shù)式接口,才可以轉(zhuǎn)換為lambda表達(dá)式
有且只有一個(gè)抽象方法的接口被成為函數(shù)式接口!
函數(shù)式接口可以顯式的被@FunctionalInterface所表示,當(dāng)被標(biāo)識(shí)的接口不滿足規(guī)定時(shí),編譯器會(huì)提示報(bào)錯(cuò)
br/>Lambda表達(dá)式的重要特征
可選類型聲明:不需要AxiTrader返傭www.kaifx.cn/broker/axitrader.html聲明參數(shù)類型,編譯器可以統(tǒng)一識(shí)別參數(shù)值。
可選的參數(shù)圓括號(hào):一個(gè)參數(shù)無需定義圓括號(hào),但多個(gè)參數(shù)需要定義圓括號(hào)。
可選的大括號(hào):如果主體包含了一個(gè)語句,就不需要使用大括號(hào)。
可選的返回關(guān)鍵字:如果主體只有一個(gè)表達(dá)式返回值則編譯器會(huì)自動(dòng)返回值,大括號(hào)需要指定明表達(dá)式返回了一個(gè)數(shù)值。
使用Lambda表達(dá)式的優(yōu)缺點(diǎn)
優(yōu)點(diǎn)
使用Lambda表達(dá)式可以簡化接口匿名內(nèi)部類的使用,可以減少類文件的生成,可能是未來編程的一種趨勢。
缺點(diǎn)
使用Lambda表達(dá)式會(huì)減弱代碼的可讀性,而且Lambda表達(dá)式的使用局限性比較強(qiáng),只能適用于接口只有一個(gè)抽象方法時(shí)使用,不宜調(diào)試。
函數(shù)式接口
只有函數(shù)式接口,才可以轉(zhuǎn)換為lambda表達(dá)式
有且只有一個(gè)抽象方法的接口被成為函數(shù)式接口!
函數(shù)式接口可以顯式的被@FunctionalInterface所表示,當(dāng)被標(biāo)識(shí)的接口不滿足規(guī)定時(shí),編譯器會(huì)提示報(bào)錯(cuò)
public class Demo01 {
public static void main(String[] args) {
// 1.傳統(tǒng)方式 需要new接口的實(shí)現(xiàn)類來完成對(duì)接口的調(diào)用
ICar car1 = new IcarImpl();
car1.drive();
// 2.匿名內(nèi)部類使用
ICar car2 = new ICar() {@Override
br/>@Override
System.out.println("Drive BMW");
}
};
car2.drive();
// 3.無參無返回Lambda表達(dá)式
ICar car3 = () -> {System.out.println("Drive Audi");};
car3.drive();
// 4.無參無返回且只有一行實(shí)現(xiàn)時(shí)可以去掉{}讓Lambda更簡潔
ICar car4 = () -> System.out.println("Drive Ferrari");
car4.drive();
// 去查看編譯后的class文件 大家可以發(fā)現(xiàn) 使用傳統(tǒng)方式或匿名內(nèi)部類都會(huì)生成額外的class文件,而Lambda不會(huì)
}
}
interface ICar {
void drive();
}
class IcarImpl implements ICar {@Override
br/>@Override
System.out.println("Drive Benz");
}
}
案例2 有參有返回值
public class Demo02 {
public static void main(String[] args) {
// 1.有參無返回
IEat eat1 = (String thing) -> System.out.println("eat " + thing);
eat1.eat("apple");
// 參數(shù)數(shù)據(jù)類型可以省略
IEat eat2 = (thing) -> System.out.println("eat " + thing);
eat2.eat("banana");
// 2.多個(gè)參數(shù)
ISpeak speak1 = (who, content) -> System.out.println(who + " talk " + content);
speak1.talk("John", "hello word");
// 3.返回值
IRun run1 = () -> {
return 10;
};
run1.run();
// 4.返回值簡寫
IRun run2 = () -> 10;
run2.run();
}
}
interface IEat {
void eat(String thing);
}
interface ISpeak {
void talk(String who, String content);
}
interface IRun {
int run();
}
案例3 final類型參數(shù)
public class Demo03 {
public static void main(String[] args) {
// 全寫
IAddition addition1 = (final int a, final int b) -> a + b;
System.out.println(addition1.add(1, 2));
// 簡寫
IAddition addition2 = (a, b) -> a+b;
System.out.println(addition2.add(2, 3));
}
}
interface IAddition {
int add(final int a, final int b);}
Java8內(nèi)置的函數(shù)式接口
Java8提供了一個(gè)java.util.function包,包含了很多函數(shù)式接口,我們來介紹最為基本的4個(gè)(為了節(jié)省篇幅,去掉了源碼中的注釋)
Function接口
@FunctionalInterface
br/>}
Java8內(nèi)置的函數(shù)式接口
Java8提供了一個(gè)java.util.function包,包含了很多函數(shù)式接口,我們來介紹最為基本的4個(gè)(為了節(jié)省篇幅,去掉了源碼中的注釋)
Function接口
@FunctionalInterface
{
R apply(T t);
default Function compose(Function before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
default Function andThen(Function after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
static Function identity() {
return t -> t;
}
}
Function接口的唯一抽象方法是apply,作用是接收一個(gè)指定類型的參數(shù),返回一個(gè)指定類型的結(jié)果
public class FunctionTest1 {
public static void main(String[] args) {
FunctionTest1 ft = new FunctionTest1();
//使用lambda表達(dá)式實(shí)現(xiàn)apply方法,返回入?yún)?10。形式上如同傳遞了一個(gè)方法作為參數(shù)
int res = ft.compute(1, v -> v + 10);
System.out.println(res);//11
}
public int compute(int a, Function function) {
//使用者在使用本方法時(shí),需要去編寫自己的apply,
//傳遞的funtion是一個(gè)行為方法,而不是一個(gè)值
return function.apply(a);
}
}
默認(rèn)方法compose作用是傳入?yún)?shù)后,首先執(zhí)行compose方法內(nèi)的Function的apply方法,然后將其返回值作為本Function方法的入?yún)ⅲ{(diào)用apply后得到最后返回值
public class FunctionTest2 {
public static void main(String[] args) {
FunctionTest2 ft = new FunctionTest2();
//調(diào)用compose
//先+8,然后將得到的值3
System.out.println(ft.compute(2, v -> v
3, v -> v + 8));//30
}
public int compute(int a, Function function1, Function function2) {
//將function2先接收入?yún),調(diào)用apply后,將返回值作為新的入?yún)?,傳入function1,調(diào)用apply返回最后結(jié)果
return function1.compose(function2).apply(a);
}
}
默認(rèn)方法andThen與compose正好相反,先執(zhí)行本Function的apply,然后將結(jié)果作為andThen方法參數(shù)內(nèi)的Function的入?yún)?,調(diào)用apply后返回最后結(jié)果
public class FunctionTest3 {
public static void main(String[] args) {
FunctionTest3 ft = new FunctionTest3();
//調(diào)用andThen
//先3,然后將得到的值+8
System.out.println(ft.compute(2, v -> v
3, v -> v + 8));//14
}
public int compute(int a, Function function1, Function function2) {
//將function2先接收入?yún),調(diào)用apply后,將返回值作為新的入?yún)?,傳入function1,調(diào)用apply返回最后結(jié)果
return function1.andThen(function2).apply(a);
}
}
靜態(tài)方法identity的作用是傳入啥返回啥,這里就不寫例子了
Consumer接口
package java.util.function;
import java.util.Objects;@FunctionalInterface
br/>@FunctionalInterface
{
void accept(T t);
default Consumer andThen(Consumer after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
Consumer接口中accept方法的作用是接收指定參數(shù)類型,無返回值,重點(diǎn)在于內(nèi)部消費(fèi)
Consumer consumer = s -> System.out.println("hello " + s);
consumer.accept("mike");// hello mike
默認(rèn)方法andThen作用是連續(xù)消費(fèi),從本Consumer開始,從外到內(nèi),針對(duì)同一入?yún)ⅰ?br/>Consumer consumer = s -> System.out.println("hello " + s);
Consumer consumer2 = s -> System.out.println("nice to meet you " + s);
consumer.andThen(consumer2).accept("mike");
//hello mike
//nice to meet you mike
Predicate接口
package java.util.function;
import java.util.Objects;@FunctionalInterface
br/>@FunctionalInterface
{
boolean test(T t);
default Predicate and(Predicate other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
default Predicate negate() {
return (t) -> !test(t);
}
default Predicate or(Predicate other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
static Predicate isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
}
Predicate中的test方法,傳入指定類型參數(shù),返回布爾類型的結(jié)果,用于判斷,斷言
//判斷一個(gè)數(shù)是否是偶數(shù)
Predicate predicate = b -> n % 2 == 0;
System.out.println(predicate.test(3));//false
默認(rèn)方法and顧名思義,將本Predicate和and參數(shù)中的Predicate對(duì)同一入?yún)⑦M(jìn)行test的結(jié)果進(jìn)行【與】操作。
negate方法對(duì)test的結(jié)果進(jìn)行【非】操作
or方法對(duì)兩個(gè)Predicate的test結(jié)果進(jìn)行【或】操作
靜態(tài)方法isEqual將其入?yún)⑴ctest方法的入?yún)⑦M(jìn)行equals比較
System.out.println(Predicate.isEqual(1).test(1));//true
Supplier接口
package java.util.function;@FunctionalInterface
br/>@FunctionalInterface
{
T get();
}
Supplier意為供應(yīng),只有一個(gè)方法get,不接收任何參數(shù),只返回指定類型結(jié)果
Supplier sup = () -> "hello world";
System.out.println(sup.get());
常用方法:
1、 Stream filter(Predicate predicate); 過濾(方法參數(shù)有參有返回值,返回值為boolean類型)boolean test(T t)
2、 Stream map(Function mapper); 將當(dāng)前流中的T類型數(shù)據(jù)轉(zhuǎn)換為另一種R類型的流。(有參有返回值) R apply(T t)
3、 void forEach(Consumer action); (有參無返回值)void accept(T t)
4、 函數(shù)原型為Stream distinct(),作用是返回一個(gè)去除重復(fù)元素之后的Stream。
5、 sorted()
排序函數(shù)有兩個(gè),一個(gè)是用自然順序排序,一個(gè)是使用自定義比較器排序,函數(shù)原型分別為Stream sorted()和Stream sorted(Comparator comparator)。
Comparator接口方法:int compare(T o1, T o2)
Stream stream= Stream.of(“I”, “l(fā)ove”, “you”, “too”);stream.sorted((str1, str2) -> str1.length()-str2.length()) .forEach(str -> System.out.println(str));6、 Collect
// 將Stream轉(zhuǎn)換成容器或Map
Stream stream = Stream.of(“I”, “l(fā)ove”, “you”, “too”);
List list = stream.collect(Collectors.toList());
Set set = stream.collect(Collectors.toSet());
Map map = stream.collect(Collectors.toMap(Function.identity(), String::length));上述代碼能夠滿足大部分需求,但由于返回結(jié)果是接口類型,我們并不知道類庫實(shí)際選擇的容器類型是什么,有時(shí)候我們可能會(huì)想要人為指定容器的實(shí)際類型,這個(gè)需求可通過Collectors.toCollection(Supplier collectionFactory)方法完成。// 使用toCollection()指定規(guī)約容器的類型
ArrayList arrayList = stream.collect(Collectors.toCollection(ArrayList::new));
HashSet hashSet = stream.collect(Collectors.toCollection(HashSet::new));使用collect()生成Map
1.使用Collectors.toMap()生成的收集器,用戶需要指定如何生成Map的key和value。
2.使用Collectors.partitioningBy()生成的收集器,對(duì)元素進(jìn)行二分區(qū)操作時(shí)用到。
3.使用Collectors.groupingBy()生成的收集器,對(duì)元素做group操作時(shí)用到。

成都創(chuàng)新互聯(lián)長期為上1000家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對(duì)不同對(duì)象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺(tái),與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為錦屏企業(yè)提供專業(yè)的做網(wǎng)站、成都網(wǎng)站制作,錦屏網(wǎng)站改版等技術(shù)服務(wù)。擁有十載豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開發(fā)。


當(dāng)前題目:Java之Lambda表達(dá)式使用
網(wǎng)站URL:http://weahome.cn/article/gihosi.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部