閑聊
Java 一直以來是使用最廣泛的編程語言之一,有很多人擔心在為她的未來擔心。但隨著 Java8 的橫空出世和即將發布的 Java9 讓 Java 迎來了第二春。Java8 最大的改變是引入了函數式編程,Java9 引入了模塊化編程。函數式和模塊化編程 擁有非常美好的未來,很多優秀的編程語言如 JavaScript 和 Scala 都擁有這些特性。
我們為什么要學習 Java8 的函數式編程?
- 為了編寫出更加簡單、干凈、易讀的代碼。
- 為了簡化集合的操作。
- 為了簡單地使用并行計算提高程序的性能。
什么是函數式編程
函數式編程的核心是:在思考問題時,使用不可變值和函數,函數對一個值進行處理,映射成另一個值。
面向對象編程是對數據進行抽象,而函數式編程是對行為進行抽象。
當看到上面的有點晦澀難懂的概念時,我相信大家和我一樣都是一臉蒙逼。先別急,其實我們都有接觸過函數式編程。可能你們會有疑問,不是 Java8 才引入函數式編程么,我們之前也沒使用過 Java8 。為了消除大家的疑惑,我們先看看清單一中的代碼。
清單一
public class Calculater {
public static void main(String[] args) {
final int a = 1, b = 2;
int result = add(new IIntegerMath() {
@Override
public int operation() {
return a + b;
}
});
System.out.println(result);
}
public static int add(IIntegerMath iIntegerMath) {
return iIntegerMath.operation();
}
}
interface IIntegerMath {
int operation();
}
在清單一中我創建了一個類 Calculater 和一個接口 IIntegerMath 。在 Calculater 的 main 方法中,我調用了 Calculater 的靜態方法 add 。在調用 add 方法時,我 new 了一個實現 IIntegerMath 接口的匿名內部類對象作為 add 方法的第參數。在匿名內部內中實現了具體的 operation 方法。
其實在給 add 方法傳參數時,我們真正需要的是一個行為,也就是 IIntergerMath 接口中的 operaton 方法。這就是函數式編程要做的事,對行為進行抽象。「ps: 在這里我對函數式編程是對行為進行抽象這個概念解釋的還不是很清楚,我相信你們通過具體的代碼會有更加深刻清晰地理解。」
我相信大家有注意到, main 方法中的變量 a 和 b 被定義成了 final 類型的。因為如果在匿名內部類只能調用外部類的 final 變量。在 operation 方法中我們將 a 和 b 映射成了另一個值。在調用 add 方法時,我們在用函數式編程解決問題,我們在 add 方法中傳入了一個方法(函數) operation ,而 operation 將不可變值 a 和 b 映射成了另一個值。
「ps: 我不知道我是否已將函數式編程的概念表達清楚了,如果大家有更好的見解,可以分享出來。」
初識 Lambda 表達式
我相信大家已經發現,我用清單一中的代碼解釋什么是函數式編程顯得非常牽強。因為清單一中的代碼是 Java8 之前的寫法,屬于命令式代碼。何為命令式代碼?我是這么理解的,在寫一段關鍵代碼的同時要附加上很多樣板式代碼,這些樣板式代碼讓真正有價值的部分黯然失色。在清單一中,你們會發現在調用 add 方法式,我們需要的僅僅是 operation 方法中的 return a + b,而其他的代碼顯得特別多余,這些多余的代碼就屬于樣板式代碼。
命令式風格的代碼并不能讓 Java 擁有函數式編程的特性。所以在 Java 8 引入了 Lambda 表達式。在本文中,我只會將清單一中的代碼用 Lambda 表達式(見清單二)再重寫一遍,將兩種風格的代碼呈現出來做一個對比,我會在之后的博客中詳細介紹 Lambda 表達式。
清單二
public class Calculater {
public static void main(String[] args) {
int a = 1, b = 2;
int result = add(() -> a + b);
System.out.println(result);
}
public static int add(IIntegerMath iIntegerMath) {
return iIntegerMath.operation();
}
}
interface IIntegerMath {
int operation();
}
大家看到清單二中的代碼是不是有大吃一驚,我就用一行代碼做了清單一中 n 多行代碼才能完成的事。這就是 Lambda 表達式的神奇之處,清單二中的 Lambda 表達式 () -> a + b 能夠清晰地詮釋函數式編程的核心思想。你們可能還是不理解我為什么要這么說,沒事,我會在之后的博客中和大家一起深入地學習和探索 Lambda 表達式。
彩蛋
我以后會堅持在每篇博客的末尾丟一個彩蛋,這個彩蛋可能是我認為非常好的書或者微信公號等等。
這次我要向大家推薦 stormzhang 。我從大三就開始關注他的公號,我一直在看他的文章。stormzhang 的文章種類很多,包括技術,理財,人生,職場等等。無論你是屬于哪個行業,我相信 stormzhang 的文章都會對你有所益。 stormzhang 目前就職于上海薄荷信息科技有限公司,擔任公司的技術主管。下圖是他的公號的二維碼。
