Java8新特性:Function接口和Lambda表達式參考


Lambda基本:https://blog.csdn.net/wargon/article/details/80656575

https://www.cnblogs.com/hyyq/p/7425666.html

四大核心函數式編程接口:

https://blog.csdn.net/a879611951/article/details/80104014

https://blog.csdn.net/chuji2012/article/details/77871011

函數式編程教程(阮一峰):

http://www.ruanyifeng.com/blog/2017/02/fp-tutorial.html

Function接口結合Lambda表達式實現:

https://blog.csdn.net/huo065000/article/details/78964382

https://segmentfault.com/a/1190000012248864

Stream,方法引用和this:

https://www.cnblogs.com/aoeiuv/p/5911692.html

https://blog.csdn.net/blacksoil55/article/details/78359045

 

四大函數式編程接口的意義在於,普通類方法在定義以它們作為函數式的參數后,可以在類方法中直接調用它們的apply,consume等方法,傳入參數,獲取結果等,返回。在調用普通類方法時,傳入lamda表達式作為這些函數式編程接口的實例,就是實現了apply,consume,test這些(唯一)抽象方法。這些方法有的接收入參返回出參,有的不返回,有的無入參,有的返回boolean等。注意應用lamda表達式的特性,如果是一句話表達式,表達式結果即函數式接口的抽象方法返回值;多行需要加{}且每句加分號。

如果不用這些函數式接口,我們就需要自己先定義一個函數式編程接口(詳見lamda表達式入門),再定義普通類方法以我們自定義的函數式接口為參數,在類方法中調用函數式接口方法。然后在類方法調用時傳入lamda表達式。

例子:

authorityList.stream().filter(authority ->
!StrUtil.equals(authority.getAuthority(), "ROLE_USER"))
.forEach(authority -> {
Set<MenuVO> menuVOSet = menuService.findMenuByRole(authority.getAuthority());
CollUtil.addAll(urls, menuVOSet);
});

其中filter的參數是Predicate函數式接口:

Stream<T> filter(Predicate<? super T> predicate);

filter這個普通類方法的一個實現為:

@Override
public final Stream<P_OUT> filter(Predicate<? super P_OUT> predicate) {
Objects.requireNonNull(predicate);
return new StatelessOp<P_OUT, P_OUT>(this, StreamShape.REFERENCE,
StreamOpFlag.NOT_SIZED) {
@Override
Sink<P_OUT> opWrapSink(int flags, Sink<P_OUT> sink) {
return new Sink.ChainedReference<P_OUT, P_OUT>(sink) {
@Override
public void begin(long size) {
downstream.begin(-1);
}

@Override
public void accept(P_OUT u) {
if (predicate.test(u))
downstream.accept(u);
}
};
}
};
}

里面就調用了Predicate函數式接口的test方法。

對filter這個普通類方法的實際調用為:

authorityList.stream().filter(authority ->
!StrUtil.equals(authority.getAuthority(), "ROLE_USER"))

也就是傳入了lamda表達式,作為Predicate接口的實現,其中的

 !StrUtil.equals(authority.getAuthority(), "ROLE_USER")

就是Predicate接口的test方法的實現,接收了authority 作為參數,省略了return,返回的就是表達式執行結果,一個boolean類型值。

 

關於Stream,Optional接口的例子:

urls.stream().filter(menu -> StrUtil.isNotEmpty(menu.getUrl())
&& antPathMatcher.match(menu.getUrl(), request.getRequestURI())
&& request.getMethod().equalsIgnoreCase(menu.getMethod()))
.findFirst().ifPresent(menuVO -> hasPermission.set(true));

這里stream和filter方法(filter方法語義原理見上文分析)均返回Stream,代表Collection容器的元素流對象,findFirst返回Optional,代表包裝的可能存在的流元素,其中的value代表Collection中的實際元素值。

ifPresent方法定義為:

public void ifPresent(Consumer<? super T> consumer) {
if (value != null)
consumer.accept(value);
}

可見這里的語義是判斷Collection中第一個元素是否非空,非空則執行Consumer接口的lamda表達式,將一個權限標識設置為true(判斷這個權限標識來決定該用戶是否有權限訪問該鏈接)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM