注:部分素材來(lái)源Lambda表達(dá)式及函數(shù)式接口介紹-51CTO學(xué)院
? ? ? ? ? ?最近在看一些三方框架的時(shí)候,發(fā)現(xiàn)在這些框架中大量的使用了java8的新特性,比如隨處可見(jiàn)的lamda表達(dá)式以及Stream類的很多騷操作,看的是一臉懵逼!在當(dāng)今社會(huì),顛覆在時(shí)時(shí)刻刻的上演,故步自封只能被無(wú)情的淘汰!擁抱變化這是你我唯一能做的!
? ? ? ? 回到正題,如何看懂框架源碼中這些“奇奇怪怪”的代碼(不明覺(jué)厲),因此很有必要學(xué)習(xí)一下java8的某些重要的新特性,Lamda表達(dá)式當(dāng)仁不讓。
? ? ? ? 我們先了解一下基本的理論知識(shí)
? ? ? ? 1、什么是Lamda表達(dá)式
????????????Lambda表達(dá)式是?Java8?中最重要的新功能之一。Lambda表達(dá)式是對(duì)象,是一個(gè)函數(shù)式接口的實(shí)例。使用?Lambda?表達(dá)式可以替代只有一個(gè)抽象函數(shù)的接口實(shí)現(xiàn),告別匿名內(nèi)部類,代碼看起來(lái)更簡(jiǎn)潔易懂。Lambda表達(dá)式同時(shí)還提升了對(duì)集合、框架的迭代、遍歷、過(guò)濾數(shù)據(jù)的操作。
? ? ? ? 2、Lamda表達(dá)式的語(yǔ)法格式
? ??????????args -> expr或者(Object… args) -> {函數(shù)式接口抽象方法實(shí)現(xiàn)邏輯},()里面參數(shù)的個(gè)數(shù),根據(jù)函數(shù)式接口里面抽象方法的參數(shù)個(gè)數(shù)來(lái)決定。當(dāng)只有一個(gè)參數(shù)的時(shí)候,()可以省略當(dāng)expr邏輯非常簡(jiǎn)單的時(shí)候,{}和return可以省略

????????2、Lamda表達(dá)式特點(diǎn)
????????????1):函數(shù)式編程
????????????2):參數(shù)類型自動(dòng)推斷
????????????3):代碼量少,簡(jiǎn)潔
? ? ? ? 3、Lamda表達(dá)式的優(yōu)點(diǎn)
? ? ? ? ?????1):更簡(jiǎn)潔的代碼
? ? ? ????? ?2):更容易的并行
????????4、如何學(xué)好Lamda表達(dá)式
? ??????????1):熟悉泛型
????????????2):多練,多用Stream API
? ? ? ? 5、Lambda表達(dá)式使用場(chǎng)景
? ??????????任何有函數(shù)式接口的地方
? ? ? ? 6、什么是函數(shù)式接口(重點(diǎn))
? ? ? ? ? ??只有一個(gè)抽象方法(Object類中的方法除外)的接口是函數(shù)式接口
????????????上面簡(jiǎn)單介紹了一些基本的理論知識(shí),理解起來(lái)可能有些抽象。怎么辦呢?下面我們具體的來(lái)學(xué)習(xí)一下,通過(guò)實(shí)例練習(xí)之后,我相信回過(guò)頭再看這些理論知識(shí)會(huì)好很多。
? ??????????我們舉個(gè)最常用的lamda應(yīng)用場(chǎng)景:

? ? ? ? ? 之前我們從理論知識(shí)中知道,lamda的應(yīng)用場(chǎng)景是在有函數(shù)式接口的地方,那么我們是不是可以理解為Runnable為函數(shù)式接口呢?我們
? ? ? ? ? 重溫一下函數(shù)式接口定義:?有且只有一個(gè)抽象方法(非Object方法)的接口為函數(shù)式接口。
我們來(lái)看下Runnable接口源碼:

不出所料,Runable接口正是標(biāo)準(zhǔn)的函數(shù)式接口。細(xì)心的同學(xué)應(yīng)該發(fā)現(xiàn)了Runnable接口上面有個(gè)注解:FunctionalInterface,該注解正是標(biāo)注該接口是函數(shù)式接口。如果不是函數(shù)式接口,添加這個(gè)注解會(huì)出錯(cuò)。舉個(gè)例子:

第一個(gè)錯(cuò)誤原因是不滿足只有一個(gè)抽象方法的條件,第二個(gè)錯(cuò)誤的原因是hashCode()方法是object方法,除去之外沒(méi)有了抽象方法,不滿足有一個(gè)抽象方法的條件,因此也不是函數(shù)式接口。
我們來(lái)了解一下jdk中一些非常常用的函數(shù)式接口(重點(diǎn)羅列常用接口),熟悉這些接口是非常必要的。(先留個(gè)印象,后面以及實(shí)際開(kāi)發(fā)中會(huì)常用到這些接口)
?????????Consumer 代表一個(gè)輸入 ? ?Supplier 代表一個(gè)輸出 ? ? ?
????????Function 代表一個(gè)輸入,一個(gè)輸出(一般輸入和輸出是不同類型的) ? ?UnaryOperator 代表一個(gè)輸入,一個(gè)輸出(輸入和輸出是相同類型的)
????????BiConsumer 代表兩個(gè)輸入
????????BiFunction 代表兩個(gè)輸入,一個(gè)輸出(一般輸入和輸出是不同類型的)BinaryOperator 代表兩個(gè)輸入,一個(gè)輸出(輸入和輸出是相同類型的)
????????我是這么記憶的,分為四組,
????????第一組單次元的輸入Supplier和輸出Comsumer,
????????第二組兩個(gè)輸入的BiConsumer
????????第三組二次元的輸入輸出不同類型Function(一般不同類型,但是也是可以同類型的)以及輸入輸出同類型UnaryOprator
????????第四組兩個(gè)輸入,一個(gè)輸出且輸入輸出不同類型的BiFunction(同時(shí)也是可以同類型的)以及輸入輸出同類型的BinaryOperator 。
下面就上面幾個(gè)常用的函數(shù)式接口進(jìn)行一些簡(jiǎn)單的試用。

User是我自定義的一個(gè)類,有age。我們使用泛型約束輸入類型,輸入user的實(shí)例,對(duì)age進(jìn)行重新賦值。





