您好,登錄后才能下訂單哦!
這篇文章主要介紹“Java8新特性Lambda表達(dá)式怎么應(yīng)用”,在日常操作中,相信很多人在Java8新特性Lambda表達(dá)式怎么應(yīng)用問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”Java8新特性Lambda表達(dá)式怎么應(yīng)用”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!
Java 8 (又稱為 jdk 1.8) 是 Java 語(yǔ)言開(kāi)發(fā)的一個(gè)主要版本。 Oracle 公司于 2014 年 3 月 18 日發(fā)布 Java 8 ,它支持函數(shù)式編程,新的 JavaScript 引擎,新的日期 API,新的Stream API 等。
可選類(lèi)型聲明:不需要聲明參數(shù)類(lèi)型,編譯器可以統(tǒng)一識(shí)別參數(shù)值。
可選的參數(shù)圓括號(hào):一個(gè)參數(shù)無(wú)需定義圓括號(hào),但多個(gè)參數(shù)需要定義圓括號(hào)。
可選的大括號(hào):如果主體包含了一個(gè)語(yǔ)句,就不需要使用大括號(hào)。
可選的返回關(guān)鍵字:如果主體只有一個(gè)表達(dá)式返回值則編譯器會(huì)自動(dòng)返回值,大括號(hào)需要指定表達(dá)式返回了一個(gè)數(shù)值。
注意:Lambda表達(dá)式適用于只有一個(gè)抽象方法的接口?。?/strong>
自定義接口
interface Fu{ void add(); }
使用匿名內(nèi)部類(lèi)實(shí)現(xiàn)接口
Fu fu = new Fu() { @Override public void add() { System.out.println("我是add方法"); } }; fu.add();
使用Lambda表達(dá)式實(shí)現(xiàn)接口
Fu fu1 = ()->{ System.out.println("我是add1方法"); }; fu1.add();
Lambda表達(dá)式基于數(shù)學(xué)中的 入 演化得名的,對(duì)應(yīng)Java中的lambda抽象,是一個(gè)匿名函數(shù),就是沒(méi)有函數(shù)名的函數(shù)。
好處
使代碼更加簡(jiǎn)潔緊湊,且可與Stream API等相結(jié)合,Lambda表達(dá)式經(jīng)常代替匿名內(nèi)部類(lèi)使用
語(yǔ)法
(參數(shù))->表達(dá)式或者(參數(shù))->{語(yǔ)句體;}
參數(shù):要重寫(xiě)方法的參數(shù)列表
->:Lambda表達(dá)式的運(yùn)算符
表達(dá)式或語(yǔ)句體:要實(shí)現(xiàn)的方法的方法體
本質(zhì)
是一種匿名函數(shù)(不是匿名內(nèi)部類(lèi)),簡(jiǎn)單說(shuō),它沒(méi)有聲明的方法、沒(méi)有訪問(wèn)修飾符、返回值聲明和名字,它是屬于函數(shù)式編程的概念
接口
interface F{ void add(); }
測(cè)試
//無(wú)參無(wú)返回值 F f = ()->{ System.out.println("我是add方法"); }; f.add();
接口
interface F{ void add(int a); }
測(cè)試
F f = (int a)->{ System.out.println("a="+a); }; f.add(12);
接口
interface F{ int add(); }
測(cè)試
F f = ()->{ return 12; }; int i = f.add(); System.out.println(i);
接口
interface F{ int add(int a); }
測(cè)試
F f = (int a)->{ return 12+a; }; int i = f.add( 12 ); System.out.println(i);
Lambda表達(dá)式中 () 的參數(shù)類(lèi)型可以省略 (int a,int b)==>(a,b)
接口中如果只有一個(gè)參數(shù),Lambda表達(dá)式中 () 可以省略 (int a)==> (a)==>a
如果方法體中只有一條執(zhí)行語(yǔ)句時(shí) 外層的 {} 可以省略
如果方法體中只有一條返回語(yǔ)句,{}和return 都可以省略
函數(shù)式接口(Functional Interface)就是一個(gè)有且僅有一個(gè)抽象方法,可以有其他普通方法,用@FunctionalInterface檢驗(yàn)是否是函數(shù)式接口。
@FunctionalInterface interface F1{ void t1(); default void t2(){//不計(jì) } static void t3(){//不計(jì) } public boolean equals(Object object);//不計(jì) }
作用:在Java中主要用在Lambda表達(dá)式和方法引用。
Consumer<T>:消費(fèi)型接口(void accept(T t))。有參數(shù),無(wú)返回值
Supplier<T>:供給型接口(T get())。有參數(shù),無(wú)返回值
Function<T,R>:函數(shù)型接口(R apply(T t))。一個(gè)輸入?yún)?shù),一個(gè)輸出參數(shù),兩種類(lèi)型可以一致,也可以不一致
Predicate<T>:斷言型接口(boolean test(T t))。輸入一個(gè)參數(shù),輸出一個(gè)boolean類(lèi)型的返回值
消費(fèi)型接口
//函數(shù)式接口的使用場(chǎng)景 public class Test03 { public static void main(String[] args) { List<Integer> list = new ArrayList<>(); Collections.addAll(list,1,2,3,6,5,4,8,9); //匿名內(nèi)部類(lèi) Consumer<Integer> con = new Consumer<Integer>() { @Override public void accept(Integer integer) { //參數(shù)代表集合中的每一個(gè)數(shù)據(jù) System.out.print(integer+" "); } }; list.forEach( con ); System.out.println(); System.out.println("=================="); //Lambda表達(dá)式1 Consumer cons = (y)->{ System.out.print(y+" "); }; list.forEach( cons ); System.out.println(); System.out.println("=================="); //Lambda表達(dá)式2 list.forEach( y-> System.out.print(y+" ") ); } }
斷言型接口
public class Test04 { public static void main(String[] args) { List<Integer> list = new ArrayList<>(); Collections.addAll(list,1,2,3,6,5,4,8,9); //匿名內(nèi)部類(lèi) Predicate<Integer> predicate = new Predicate<Integer>() { @Override public boolean test(Integer integer) { //參數(shù)o代表集合中的每一個(gè)數(shù) if (integer<=6){ return true;//刪除該數(shù)據(jù) } return false;//不刪除該數(shù)據(jù) } }; list.removeIf(predicate); list.forEach( x-> System.out.println(x) ); System.out.println("================="); //Lambda表達(dá)式 list.removeIf( y->{ if (y<=6){ return true; } return false; } ); list.removeIf(predicate); list.forEach( x-> System.out.println(x) ); System.out.println("================="); } }
方法引用通過(guò)方法的名字來(lái)指向一個(gè)方法。方法引用可以使語(yǔ)言的構(gòu)造更緊湊簡(jiǎn)潔,減少冗余代碼。方法引用使用一對(duì)冒號(hào) :: 。
//方法引用 public class Test05 { public static void main(String[] args) { List<Integer> list = new ArrayList<>(); Collections.addAll(list,4,8,9); //使用Lambda表達(dá)式 list.forEach( x-> System.out.println(x) ); System.out.println("=================="); //方法引用 //使用場(chǎng)景,參數(shù)傳遞過(guò)來(lái)不做任何處理,直接輸出的就可以使用方法引用 list.forEach(System.out::println); } }
構(gòu)造器引用:它的語(yǔ)法是Class::new,或者更一般的Class< T >::new
final Car car = Car.create( Car::new ); final List< Car > cars = Arrays.asList( car );
靜態(tài)方法引用:它的語(yǔ)法是Class::static_method
cars.forEach( Car::collide );
特定類(lèi)的任意對(duì)象的方法引用:它的語(yǔ)法是Class::method
cars.forEach( Car::repair );
特定對(duì)象的方法引用:它的語(yǔ)法是instance::method
final Car police = Car.create( Car::new ); cars.forEach( police::follow );
Stream(流)是一個(gè)來(lái)自數(shù)據(jù)源的元素隊(duì)列并支持聚合操作
元素是特定類(lèi)型的對(duì)象,形成一個(gè)隊(duì)列。 Java中的Stream并不會(huì)存儲(chǔ)元素,而是按需計(jì)算。
數(shù)據(jù)源 流的來(lái)源。 可以是集合,數(shù)組,I/O channel, 產(chǎn)生器generator 等。
聚合操作 類(lèi)似SQL語(yǔ)句一樣的操作, 比如filter, map, reduce, find, match, sorted等。
和以前的Collection操作不同, Stream操作還有兩個(gè)基礎(chǔ)的特征:
Pipelining: 中間操作都會(huì)返回流對(duì)象本身。 這樣多個(gè)操作可以串聯(lián)成一個(gè)管道, 如同流式風(fēng)格(fluent style)。 這樣做可以對(duì)操作進(jìn)行優(yōu)化, 比如延遲執(zhí)行(laziness)和短路( short-circuiting)。
內(nèi)部迭代: 以前對(duì)集合遍歷都是通過(guò)Iterator或者For-Each的方式, 顯式的在集合外部進(jìn)行迭代, 這叫做外部迭代。 Stream提供了內(nèi)部迭代的方式, 通過(guò)訪問(wèn)者模式(Visitor)實(shí)現(xiàn)。
創(chuàng)建Stream:從一個(gè)數(shù)據(jù)源(集合、數(shù)組)中獲取
中間操作:一個(gè)操作的中間鏈,對(duì)數(shù)據(jù)源的數(shù)據(jù)進(jìn)行處理
終止操作:一個(gè)終止操作,執(zhí)行中間操作鏈,并產(chǎn)生結(jié)果
排序去重
//Stream 流式編程 public class StreamTest01 { public static void main(String[] args) { //需求:有一堆數(shù)據(jù),且有重復(fù)值,要求有序去除重復(fù)值 List<Integer> list = new ArrayList<>(); Collections.addAll(list,56,89,75,64,24,25,24,89,56,75); //流式編程處理 //獲取stream Stream<Integer> stream = list.stream(); //中間操作 stream = stream.distinct()//去重操作 .sorted();//排序 //終止操作 stream.forEach( x->{//輸出集合中元素 System.out.println(x); } ); } }
中間操作
stream = stream.distinct()//去重操作 .sorted();//排序 .limit( 4 );//取前四個(gè)元素 .skip( 2 );//跳過(guò)前幾個(gè)元素 .map( x->x+4 );//每一個(gè)元素加上特定的值 .filter( x->{//過(guò)濾操作,true正常返回,false不返回 if (x>=25){ return true; } return false; } );
串行流
Stream<Integer> stream = list.stream();//串行流
并行流
Stream<Integer> stream1 = list.parallelStream();//并行流
Optional 類(lèi)是一個(gè)可以為null的容器對(duì)象。如果值存在則isPresent()方法會(huì)返回true,調(diào)用get()方法會(huì)返回該對(duì)象。
Optional 是個(gè)容器:它可以保存類(lèi)型T的值,或者僅僅保存null。Optional提供很多有用的方法,這樣我們就不用顯式進(jìn)行空值檢測(cè)。
Optional 類(lèi)的引入很好的解決空指針異常。
Optional 類(lèi)的方法
static <T> Optional<T> empty() 返回空的 Optional 實(shí)例。
boolean equals(Object obj) 判斷其他對(duì)象是否等于 Optional。
Optional<T> filter(Predicate<? super <T> predicate) 如果值存在,并且這個(gè)值匹配給定的 predicate,返回一個(gè)Optional用以描述這個(gè)值,否則返回一個(gè)空的Optional。
<U> Optional<U> flatMap(Function<? super T,Optional<U>> mapper) 如果值存在,返回基于Optional包含的映射方法的值,否則返回一個(gè)空的Optional
T get() 如果在這個(gè)Optional中包含這個(gè)值,返回值,否則拋出異常:NoSuchElementException
int hashCode() 返回存在值的哈希碼,如果值不存在 返回 0。
void ifPresent(Consumer<? super T> consumer) 如果值存在則使用該值調(diào)用 consumer , 否則不做任何事情。
boolean isPresent() 如果值存在則方法會(huì)返回true,否則返回 false
<U>Optional<U> map(Function<? super T,? extends U> mapper) 如果有值,則對(duì)其執(zhí)行調(diào)用映射函數(shù)得到返回值。如果返回值不為 null,則創(chuàng)建包含映射返回值的Optional作為map方法返回值,否則返回空Optional。
static <T> Optional<T> of(T value) 返回一個(gè)指定非null值的Optional。
static <T> Optional<T> ofNullable(T value) 如果為非空,返回 Optional 描述的指定值,否則返回空的 Optional。
T orElse(T other) 如果存在該值,返回值, 否則返回 other。
T orElseGet(Supplier<? extends T> other) 如果存在該值,返回值, 否則觸發(fā) other,并返回 other 調(diào)用的結(jié)果。
<X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) 如果存在該值,返回包含的值,否則拋出由 Supplier 繼承的異常
String toString() 返回一個(gè)Optional的非空字符串,用來(lái)調(diào)試
到此,關(guān)于“Java8新特性Lambda表達(dá)式怎么應(yīng)用”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。