順便一提default與lambda

default 做用:在接口中寫方法體,如圖java

關於default關鍵字的詳細說明:spring

https://blog.csdn.net/SnailMann/article/details/80231593dom

 

lambda ide

使用方法:先看一個例子函數

這是在實際業務開發中的代碼,是使用Spring Data JPA 的 Specification 來進行復雜查詢 :性能

Pageable pageable =  PageRequest.of(page.getCurrent()-1,page.getSize(), Sort.Direction.DESC,"id");

org.springframework.data.domain.Page< CmsMaintainPrevent> pageResult = CmsMaintainPreventRepository.findAll(new Specification< CmsMaintainPrevent>() {
@Override
public Predicate toPredicate(Root< CmsMaintainPrevent> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {

return cb.and(cb.equal(root.get("delFlag").as(String.class),String.valueOf(params.get("delFlag"))));
}
},pageable);

lambda 用法以下:
org.springframework.data.domain.Page< CmsMaintainPrevent> pageResult =  CmsMaintainPreventRepository.findAll(
(Specification<CmsMaintainPrevent>) (root, criteriaQuery, cb)
->
cb.and(cb.equal(root.get("delFlag").as(String.class),String.valueOf(params.get("delFlag")))),pageable);
代碼的瞬間簡潔了很多(lambda表達方式會形成性能降低5倍左右,具體能夠本身測試)

詳情分析:

 

經過Lamda表達式,能夠變換爲:測試

 

new Thread(() -> System.out.println("thread"));ui

 

針對這種實行,咱們怎麼理解呢?其實很簡單,上看一下上述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

相關文章
相關標籤/搜索