針對這種實行,咱們怎麼理解呢?其實很簡單,上看一下上述lambda表達式的語法:() -> {}(): 括號就是接口方法的括號,接口方法若是有參數,也須要寫參數。只有一個參數時,括號能夠省略。-> : 分割左右部分的,沒啥好講的。{} : 要實現的方法體。只有一行代碼時,能夠不加括號,能夠不寫return。spa
不過看到這裏我相信有些小夥伴已經許意識到了,若是接口中有多個方法時,那麼按照上面的邏輯lambda表達式恐怕沒辦法表示了。的確是這樣,並不是任何接口都支持lambda表達式。.net
而適用於lambda表達式的接口稱之爲函數型接口。說白了,函數型接口就是隻有一個抽象方法的接口。
函數式接口
其實以前在講Lambda表達式的時候提到過,所謂的函數式接口,固然首先是一個接口,而後就是在這個接口裏面只能有一個抽象方法。
這種類型的接口也稱爲SAM接口,即Single Abstract Method interfaces。
1.一、函數式接口基本語法
它們主要用在Lambda表達式和方法引用(實際上也可認爲是Lambda表達式)上。
如定義了一個函數式接口以下:
那麼就可使用Lambda表達式來表示該接口的一個實現(注:JAVA 8 以前通常是用匿名類實現的):
GreetingService greetService1 = message -> System.out.println("Hello " + message);
1.二、FunctionalInterface註解
關於@FunctionalInterface註解Java 8爲函數式接口引入了一個新註解@FunctionalInterface,主要用於編譯級錯誤檢查,加上該註解,當你寫的接口不符合函數式接口定義的時候,編譯器會報錯。
正確例子,沒有報錯:
1.三、用法提醒
ERROR:接口中包含了兩個抽象方法,違反了函數式接口的定義,IDE會直接報錯。
Tips:加不加@FunctionalInterface對於接口是否是函數式接口沒有影響,該註解知識提醒編譯器去檢查該接口是否僅包含一個抽象方法
1.四、默認方法
函數式接口裏是能夠包含默認方法,由於默認方法不是抽象方法,其有一個默認實現,因此是符合函數式接口的定義的;
1.五、靜態方法
函數式接口裏是能夠包含靜態方法,由於靜態方法不能是抽象方法,是一個已經實現了的方法,因此是符合函數式接口的定義的;
以下代碼不會報錯:
1.六、Object裏的public方法
函數式接口裏是能夠包含Object裏的public方法,這些方法對於函數式接口來講,不被當成是抽象方法(雖然它們是抽象方法);由於任何一個函數式接口的實現,默認都繼承了Object類,包含了來自java.lang.Object裏對這些抽象方法的實現;
以下代碼不會報錯:
進階
有了上面的基礎,咱們稍稍聊一些深刻的lambda表達式。lambda表達式還有兩種簡化代碼的手段,它們是方法引用、構造引用。
方法引用是什麼呢?若是咱們要實現接口的方法與另外一個方法A相似,(這裏的相似是指參數類型與返回值部分相同),咱們直接聲明A方法便可。也就是,再也不使用lambda表達式的標準形式,改用高級形式。不管是標準形式仍是高級形式,都是lambda表達式的一種表現形式。
Function function1 = (x) -> x;Function function2 = String::valueOf;
對比Function接口的抽象方法與String的value方法,能夠看到它們是相似的。
方法引用的語法:
對象::實例方法類::靜態方法類::實例方法
前兩個很容易理解,至關於對象調用實例方法,類調用靜態方法同樣。只是第三個須要特殊說明。
Compare<Boolean> c = String::equals;
也就是「類::實例方法」的形式。
構造引用
提煉一下構造引用的語法:類名::new
引用自:
https://baijiahao.baidu.com/s?id=1614680282522143196&wfr=spider&for=pc
關於lambda更加詳細的說明:
https://blog.csdn.net/wxycm/article/details/80429299