天天看點

java 8 lambda 函數_「Java 8 函數式程式設計」讀書筆記——lambda表達式

本文是「Java 8 函數式程式設計」第二章的讀書筆記。

Lambda引入的變化

Lambda表達式,是一種緊湊的、傳遞行為的方式,從程式設計思想上來講,就是代碼即資料。

過去的Java中,存在大量的匿名内部類的使用,會建立一個匿名内部類傳入調用的方法中。這種傳統的方式,會造成備援的、不易閱讀的代碼。

于是Lambda誕生了。Lambda的文法簡化了使用匿名内部類時的模闆代碼,讓程式員專注于編寫想要執行的行為,也讓代碼更加簡潔易讀。

Lambda表達式的形式

Runnable runable = () -> System.out.println("Hello Lambda");//1

runable = () -> {

System.out.print("Hello");

System.out.println(" Lambda");

};//2

ActionListener listener = event -> System.out.println("get event");//3

BinaryOperator add = (x, y) -> x + y;//4

BinaryOperator minux = (Long x, Long y) -> x - y;//5

常見的Lambda表達式有以上5種,每個Lambda表達式都可以分為三個部分:

參數部分:() event (x, y) (Long x, Long y)

将參數和表達式主體分開的符号:->

表達式主體

參數的形式

Lambda表達式可以看作是匿名内部類的簡寫形式,參數也就是使用匿名内部類時實作的方法的參數。

有的方法不需要參數,如Runnable的run方法,是以使用()代表參數部分。

有的方法隻需要一個參數且類型确定,如ActionListener.actionPerformed方法,可以直接使用參數,不需要指定類型,也不需要加括号。

有多個參數時,必須要加上括号,把參數擴起來

當聲明參數類型時,無論有多少個參數,都需要加括号

表達式主體的形式

表達式可以隻有一行代碼,也可以有多行代碼;有的表達式有傳回值,有的沒有。

隻有一行代碼的表達式不需要{}

如果有傳回值,不用寫return,表達式會把這行代碼的傳回值作為傳回值

如果使用了{},則需要顯式的寫出return

有多行代碼的表達式必須使用{}

如果有傳回值,需要顯式的寫return

引用值,而不是變量

匿名内部類中,如果想要引用其所在方法中的變量,需要将其聲明為final。這意味着你實際引用的是一個值,而不是變量。

在Java 8中,雖然可以引用非final的變量,但這個變量必須是既成事實上的final,如果對變量進行修改,将無法通過編譯。這意味着Lambda表達式仍然是引用的一個值,而不是變量。

實際上可以通過使用數組來繞開編譯器,但是這樣做之前應該考慮一下你的代碼邏輯是否正确。

函數接口

隻有一個抽象方法的接口叫做函數接口。

JDK中最重要的函數接口:

Interface

Argument

Return

e.g.

Predicate

T

boolean

fliter

Consumer

T

void

forEach

Function

T

R

map

Supplier

None

T

factory function

UnaryOperator

T

T

modify String

BinaryOperator

(T, T)

T

add two instances

類型推斷

Java 8為新成員Lambda表達式提供了類型推斷的支援,在不需要聲明參數類型的Lambda表達式中表現的有為明顯。形如:

BinaryOperator add = (x, y) -> x + y;

的表達式得以通過編譯并正确執行,就是因為JVM通過泛型參數Integer推斷出了方法參數的類型。