Lambda表示式
Lambda表示式並不是什麼新概念,自Alonzo Church提出Lambda微積分的概念以來,已經有30個年頭了,從那時開始,它們就成為許多函數語言程式設計語言的重要特性,最突出的可能要算Lisp,現在Lambda表示式已經躋身於函數語言程式設計語言的一等公民。Lambda表示式是一個匿名函式,為了演示,這裡有一個段你可能經常看到的Python程式碼段:
- list = [1, 2, 3, 6, 8,]
- print filter(Lambda x: x * 2 > 10, list)
- [6, 8]
表示式"Lambda x: x * 2 > 10"是一個Lambda函式,在執行時它是匿名的,在filter函式中執行,類似地,你可以將相同的表示式賦給一個變數進行傳遞,或呼叫函式自身:
- f = Lambda x: x * 2 > 10
- print filter(f, list)
- [6, 8]
- # Let's call f itself
- f(1)
- False
在Java中,我們目前有匿名內部類證明Lambda表示式是匿名的,當傳遞給它一個方法時,它們就是一個普通的物件,如:
- File cwd = new File(".);
- System.out.println(cwd.list(new FileFilter() {
- public boolean accept(File f) {
- return f != null && f.getName().endsWith(".java");
- }
- }));
現在可以將Lambda表示式簡單地當作一個匿名函式,在Java中,這可能意味著“回撥”,真正的遞迴和其它功能,或許實現Comparator(比較器)介面篩選集合的日子將一去不復還了,如果它們在JDK 7中完成,預計我們將看到一個更加動態的語言。
函式型別
正如前面提到的,Lambda表示式將引入另一個函數語言程式設計概念:函式型別。它僅僅指的是將函式作為物件看待,就象是一個String或BigDecimal,它允許你象其它型別那樣將其傳遞給其它函式。
閉包
你應該聽說過閉包的概念,它是另一個非常簡單的函數語言程式設計概念,它允許在一個函式中包括另一個函式,並可以在內部函式中引用外部變數,這種變數被稱作“自由變數”,因為它們不是閉包的引數,也不是區域性變數。
實際上,如果你閱讀過有關JDK 7的文章,你會發現閉包一詞的出現頻率比Lambda表示式還要多,這是因為它倆通常是一起出現的,當Lambda表示式訪問外部變數時,它就變成閉包,根據定義,閉包也是一種Lambda表示式。
高階函式
高階函式是指取得或返回另一個函式的函式,在本文開頭的Python程式碼示例中,你應該已經看到了filter函式,它就是一個高階函式,因為它的第一個引數是一個函式,這個函式用於測試列表(第二個引數)中每個元素的內容。
區域性套用函式
區域性套用函式最好解釋為“鏈條式”Lambda表示式,對於一個可接受多個引數的函式,區域性套用函式是函式轉換的過程,以便每個引數都被傳遞給函式,然後根據原始的函式呼叫返回。
- // "mul" is function that takes two arguments; both ints
- mul(5).(5); // returns 25
其它還不錯的函數語言程式設計概念
其它我認為還不錯的函數語言程式設計概念有:
◆列表解析 – 為在一行命令中生成列表(集,對映等)的語法裝飾,如“List<String> l = (for x in someOtherCollection) { x.someMethod() && x.another(); }”
◆尾遞迴 – 在語句的末尾呼叫自己的函式,編譯器(或執行時環境)可以識別它,因此程式碼可以得到明顯的優化。
函數語言程式設計有什麼意義?
問得好,函數語言程式設計的好處有許多,最明顯的是整體程式碼量更少了,不用再為檔名過濾和比較等功能實現介面,你可以直接傳遞函式了。
小結
程式設計世界總是充斥著其它新時代的思想和傳統,函數語言程式設計只是其中一個優秀的軟體開發方法,各有利弊,它可能會幫助你寫出更好的軟體。不管如何,我相信Lambda表示式專案一定可以完成,雖然它仍然存在缺陷,但它會給程式語言帶來新鮮空氣,也必將會受到開發者的歡迎。
原文作者:Alex Collins
原文名:Functional Programming Concepts in JDK 7
原文地址:http://java.dzone.com/articles/lambdas-closures-jdk-7