1.一段話了解函數式程式設計
首先說一下
函數
和
方法
的差別,簡單的可以了解為同一個東西,都是一個執行塊。前者是
面向過程
的叫法,後者是
面向對象
的叫法。是以說函數式程式設計某種程度上來說也可以了解為方法程式設計。而寫過js的同學應該知道,在js中的函數是允許把另外一個函數作為自身參數的。後來仔細看了《java8實戰》,談一下自己的了解。函數式程式設計這個概念就是讓我們用一種新的思維方式去寫java。
2.舉個栗子
我們先定義一個簡單的
People
接口。
public interface People {
void say();
}
然後定義一個
ZhangSan
類,當我們需要建立
People
執行個體的時候,顯然需要去實作這個接口裡的方法。
public class ZhangSan {
People zhangsan = new People() {
@Override
public void say() {
System.out.println("i am zhangsan");
}
};
}
同樣的,建立一個LiSi類,也需要這麼操作。
public class LiSi {
People liSi = new People() {
@Override
public void say() {
System.out.println("i am lisi");
}
};
}
發現問題了嗎?每次建立接口對象的時候,“=”右邊的格式是固定的。再者我們建立接口的目的是什麼?是為了使用他的方法。那麼可以直接使用他的方法而不建立執行個體嗎?java8是這麼做的。把上面代碼重複的部分改為:
() ->
是以上面的代碼也可以寫成
public class LiSi {
static People liSi = () -> {
System.out.println("i am lisi");
};
}
我們可以嘗試調用一下liSi的say方法。
public class LiSi {
static People liSi = () -> {
System.out.println("i am lisi");
};
public static void main(String[] args) {
liSi.say();
}
}
輸出結果: i am lisi
其中 () 是參數清單,這裡沒有使用參數。 ->是操作符,固定格式不必糾結,{}是方法體。
看到這裡你可能會有一點疑惑,我們在定義liSi這個對象的時候,也沒有指定它的say方法啊,為什麼調用say方法的時候可以實作呢?這就涉及到函數式接口的定義:
有且僅有一個抽象方法
。是以在建立lisi的時候,方法體裡實作的就是People接口裡的say方法。
當方法體裡隻有一個表達式的時候,方法體的大括号也可以省略不寫
。就像這樣:
我們通常通過
@FunctionalInterface
來标示一個函數式接口,也可以不寫,它隻是起到一個标示作用。
此時lisi就是一個People對象,
且實作了唯一的抽象方法
。現在有一個
talk
方法,需要Peopeo參數:
public static void talk(People people) {
people.say();
}
我們在調用的時候就可以用
lambda表達式
進行替換【了解這一點非常重要,搞清楚這個很友善接下來學習lamda的常用方法和流式程式設計】:
public static void main(String[] args) {
talk(() -> System.out.println("i am lisi"));
}
因為
talk
方法需要的參數是People,而我們的
() -> System.out.println("i am lisi")
則正是一個實作了People接口唯一抽象方法的執行個體。此時運作則會輸出:
i am lisi
。
了解這一點則可以開始接下來的學習,lambda常用方法.
連結: