Java 8終於引進了lambda表示式,這標誌著Java往函數語言程式設計又邁進了一小步。
在Java 8以前的程式碼中,為了實現帶一個方法的介面,往往需要定義一個匿名類並複寫介面方法,程式碼顯得很臃腫。比如常見的Comparator
介面:
String[] oldWay = "Improving code with Lambda expressions in Java 8".split(" ");
Arrays.sort(oldWay, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
// 忽略大小寫排序:
return s1.toLowerCase().compareTo(s2.toLowerCase());
}
});
System.out.println(String.join(", ", oldWay));
對於只有一個方法的介面,在Java 8中,現在可以把它視為一個函式,用lambda表示式簡化如下:
String[] newWay = "Improving code with Lambda expressions in Java 8".split(" ");
Arrays.sort(newWay, (s1, s2) -> {
return s1.toLowerCase().compareTo(s2.toLowerCase());
});
System.out.println(String.join(", ", newWay));
Java 8沒有引入新的關鍵字lambda,而是用()->{}
這個奇怪的符號表示lambda函式。函式型別不需要申明,可以由介面的方法簽名自動推匯出來,對於上面的lambda函式:
(s1, s2) -> {
return s1.toLowerCase().compareTo(s2.toLowerCase());
});
引數由Comparator<String>
自動推匯出String
型別,返回值也必須符合介面的方法簽名。
實際上,lambda表示式最終也被編譯為一個實現類,不過語法上做了簡化。
對於Java自帶的標準庫裡的大量單一方法介面,很多都已經標記為@FunctionalInterface
,表明該介面可以作為函式使用。
以Runnable
介面為例,很多時候幹活的程式碼還沒有定義class的程式碼多,現在可以用lambda實現:
public static void main(String[] args) {
// old way:
Runnable oldRunnable = new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + ": Old Runnable");
}
};
Runnable newRunnable = () -> {
System.out.println(Thread.currentThread().getName() + ": New Lambda Runnable");
};
new Thread(oldRunnable).start();
new Thread(newRunnable).start();
}
在未來的Java程式碼中,會出現越來越多的()->{}
表示式。