大話lambda-每日一招
微信公眾號:Sumslack團隊
如有問題或建議,請公眾號留言
Lambda由來
在Java編寫代碼過程中,我們可以對一個Java對象賦予一個值,比如如下代碼:
那麼我們在想,能否將一個函數賦值給一個變數呢?在JDK8之前,這是做不到的,比如無法實現類似如下的代碼:
但在其他面向對象語言中,確是可以的,比如JavaScript,可以將函數賦值給一個變數,如下:
JDK8問世之後,利用lambda就可以做到了,並且都過智能的JDK編譯器,你無需聲明作用域,入參類型(編譯器自動會推導),返回類型(編譯器自動推導),並且如果只有一條語句的話,也不需要寫{},如果只有一個入參,甚至可以省略(),最後可簡寫成這樣:
那麼,IFuncPrint是啥玩意呢?和變數類型一樣,它是一個函數式介面,在這個介面中,必須只能有唯一一個抽象函數,為了避免不小心在這個介面中編寫多個參數,可以在介面上使用註解@FunctionalInterface,這樣如果寫了多個函數,編譯器會報錯;
Lambda使用
Lambda其實是一個Java的「語法糖」,在JDK8之前,如果要傳函數為參數,只能使用匿名類,比如new Thread一個線程,必須傳入Runable的匿名類,如下:
有了Lambda之後,我們知道Runnable只有一個抽象函數:run,所以我們給Thread傳入lambda表達式也是可以的,下面代碼和上面是等價的,但代碼更加簡潔:
由於lambda表達式可以直接賦給一個變數,所以它可以作為函數參數傳入到函數體,而在JDK8之前,你就必須使用匿名類,就如上面Thread的代碼一樣;
lambda結合stream,Optional等新特性,可以大大簡化針對List,Null值的處理,使得代碼量大大減少,舉例如下:
一個對象為空時,做一些業務處理,我們可以不使用if語句判斷了
對集合類型更便捷優雅的處理,比如利用Predicate過濾集合元素,Consumer對stream結果處理
this「穿透」,lambda不會引入新作用域
在lambda表達式內部,this指針指向外部類的實例,比如以下代碼:
執行結果為:
結束語:lambda表達式作為JDK8之後,Java面向函數式編程的補充,提供了一個「語法糖」,使得我們無需使用匿名類的方式將函數通過參數形式傳入函數,並且提供了更加優雅和簡潔的語法,利用lambda表達式提供的Predicate,Consumer,Function,Supplier,UnaryOperator,BinaryOperator函數式介面,可提供針對集合更加便捷的操作,比如排序,map,複雜計算等;
關注我們的公眾號
TAG:Sumslack團隊 |