概念簡述
-
Lambda 表達式(lambda expression)是一種
表達式語法
, 注意在java里面, 它不是對象. 以下均是lambda表達式() -> "haha" a -> "hehe"
java 中,
類名::方法名
和對象::方法名
也都是 lambda 表達式 函數(shù)式接口(Functional Interface)就是一個有且僅有一個抽象方法,但是可以有多個非抽象方法的接口袜蚕。
函數(shù)式接口 與 lambda 表達式的關(guān)系
-
lambda表達式
不能直接使用,在使用之前必須初始化
. -
lambda表達式
必須借助函數(shù)式接口
來初始化. -
lambda表達式
初始化之前什么都不是,初始化之后是一個函數(shù)式接口
的實例對象.
1. lambda表達式不能直接使用,在使用之前必須初始化
下面三個lambda表達式 只是一種語法, 你無法確定它們到底是個什么東西.
() -> {}
() -> "gaga";
String::new;
2. lambda表達式
必須借助函數(shù)式接口
來初始化
以 () -> "gaga"
為例, 它是一個lambda表達式, 必須初始化才能使用, 要想初始化, 必須要借助具體的函數(shù)式接口.
下面是這個lambda表達式的初始化.
// 被 Supplier 初始化之后, 變成一個 Supplier 實例對象
Supplier<String> supplier = () -> "gaga";
// 被 Runnable 初始化之后, 變成一個 Runnable 實例對象
Runnable supplier = () -> "gaga";
// 當然你也可以自定義一個韓式式
甚至你可以自定義一個函數(shù)式接口, 如下
@FunctionalInterface
interface Haha {
Object hehe();
}
// 被 Haha 初始化之后, 變成一個 Haha 實例對象
Haha supplier = () -> "gaga";
3. lambda表達式
初始化之前什么都不是,初始化之后是一個函數(shù)式接口
的實例對象
函數(shù)式接口實例對象是一個對象, 因此是一個Object, 擁有 Object 的一切特性.
-
lambda 表達式 在初始化之前只是一種語法, 它不是對象, 也不能被引用.
// 被 Supplier 初始化之后, 變成一個 Supplier 實例對象 Supplier<String> supplier = () -> "gaga"; // 初始化之后是一個函數(shù)式接口實例對象, 因此可以被 Object 引用 Object o = arr; // 但是 你不能直接使用 Object 引用它, 因為它還未經(jīng)過初始化, 此時還不是對象. Object f = () -> "gaga"; // ERROR
此外函數(shù)式接口還有一些有趣的地方
lambda表達式
在被函數(shù)式接口初始化后成為一個對象.
在java 中, 類名::方法名
和 對象::方法名
也都是 lambda 表達式
.
因此, 對象::方法名
還能被函數(shù)式接口初始化.
示例
// supplier1 是一個函數(shù)式接口實例對象
Supplier<String> supplier1 = () -> "gaga"
// supplier1 是一個對象, 因此 supplier1::get 是一個lambda表達式, 既然是 lambda 表達式 那么能被函數(shù)式接口初始化
Supplier<String> supplier2 = supplier1::get;
// 我要連續(xù)初始化 100次, 每次初始化都相當于創(chuàng)建了一個新的實例對象
for (int i = 0; i < 100; i ++) {
supplier2 = supplier2::get
}
那么, 這個有什么用呢?
例如, 下面是一個函數(shù)式接口Haha
和一個實例Supplier
, 它們的結(jié)構(gòu)大同小異.
@FunctionalInterface
interface Haha {
Object hehe();
}
Supplier<String> supplier = () -> "gaga"
你需要一個 Haha 接口實例, 但是現(xiàn)在你只有一個 Supplier<String>
實例, 此時你就可以這樣轉(zhuǎn)換
Haha haha = supplier::get;
數(shù)組的初始化(對比lambda表達式初始化)
如果你對lambda的初始化還不了解, 那就請參照下數(shù)組的初始化, lambda表達式和數(shù)組的初始化很像.
-
{3, 4, 5, 6}
是一種表達數(shù)組的語法. 它不能直接使用,在使用之前必須初始化
. -
{3, 4, 5, 6}
必須借助具體的類型
來初始化. -
{3, 4, 5, 6}
初始化之后是一個數(shù)組
的實例對象.
int[]
是一種具體的類型,int[].class
是有意義的
// 1. 這個是數(shù)組的初始化. 初始化可不僅僅是一個賦值引用的操作.
int[] arr = {3, 4, 5, 6};
// 被 byte[] 初始化后是一個byte數(shù)組, 被 Integer[] 初始化之后是一個 Integer 數(shù)組
byte[] arr2 = {3, 4, 5, 6};
Integer[] arr3 = {3, 4, 5, 6};
// arr 初始化之后是一個對象, 因此 arr 在初始化之后可以被 Object 引用
Object o = arr;
// 但是 你不能直接使用 Object 引用它, 因為它還未經(jīng)過初始化, 此時還不是對象.
Object f = {3, 4, 5, 6}; // ERROR