你有沒有想過,每次處理只有一個抽象方法的接口時,都要寫一大段匿名內部類代碼?比如啓動一個線程,或者對集合排序,這些地方都需要實現一個只有一個方法的接口,代碼看起來總是顯得有些繁瑣。Java 8引入的Lambda表達式,就是爲了解決這種“代碼冗餘”的問題,讓我們能用更簡潔的方式實現這些簡單的函數式接口。
爲什麼需要Lambda表達式?¶
在Java 8之前,如果要使用只有一個抽象方法的接口(比如Runnable或Comparator),通常需要寫一個匿名內部類。例如,啓動一個線程時,代碼可能像這樣:
// 舊寫法:使用匿名內部類實現Runnable
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("線程運行了!");
}
}).start();
這段代碼中,new Runnable() {}是匿名內部類,包含了run()方法的實現。但對只有一行邏輯的情況來說,這種寫法顯得冗餘:需要寫new Runnable()、@Override和大括號,反而影響了代碼的簡潔性。
Lambda表達式的出現,就是爲了用更簡短的語法替代這種繁瑣的匿名內部類寫法。
什麼是函數式接口?¶
要理解Lambda表達式,首先要明白函數式接口的概念:函數式接口是隻有一個抽象方法的接口。比如:
- Runnable接口:只有一個run()方法(無參數、無返回值)。
- Comparator接口:只有一個compare(T o1, T o2)方法(兩個參數,返回int)。
Java 8還提供了很多內置函數式接口(如Consumer、Supplier等),但對初學者來說,先掌握Runnable和Comparator這類基礎接口就夠了。
Lambda表達式的語法基礎¶
Lambda表達式的核心語法是“參數列表 -> 表達式體”,具體可分爲以下幾種情況:
1. 無參數的情況¶
如果函數式接口的抽象方法沒有參數,參數列表用空括號()表示,表達式體直接寫結果。例如:
() -> System.out.println("Hello, Lambda!")
2. 1個參數的情況¶
如果只有一個參數,小括號可以省略,直接寫參數名。例如:
s -> System.out.println(s) // 等價於 (String s) -> System.out.println(s)
3. 多個參數的情況¶
參數列表用小括號包裹,類型可省略(編譯器自動推斷)。例如:
(a, b) -> a + b // 等價於 (int a, int b) -> a + b
4. 表達式體的寫法¶
- 單行表達式:如果表達式體只有一行代碼,大括號
{}可以省略,結果會自動返回。例如:(a, b) -> a - b。 - 多行表達式:如果有多行代碼,必須用大括號,且需要顯式寫
return。例如:
(a, b) -> {
int result = a * 2 + b;
return result;
}
實例演示:用Lambda簡化常見場景¶
場景1:使用Runnable接口(線程)¶
舊寫法(匿名內部類):
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("線程啓動了!");
}
}).start();
Lambda簡化後:
new Thread(() -> System.out.println("線程啓動了!")).start();
解釋:()表示無參數,->後直接寫run()的邏輯,一行代碼搞定。
場景2:使用Comparator接口(排序)¶
對字符串列表按長度排序,舊寫法:
List<String> list = Arrays.asList("apple", "banana", "cherry");
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String a, String b) {
return a.length() - b.length();
}
});
Lambda簡化後:
Collections.sort(list, (a, b) -> a.length() - b.length());
解釋:(a, b)是compare的兩個參數,->後直接返回長度差,無需大括號和return。
場景3:自定義函數式接口¶
假設我們自定義一個簡單的函數式接口Calculator,只有一個add方法:
@FunctionalInterface // 確保是函數式接口(僅一個抽象方法)
interface Calculator {
int add(int a, int b);
}
用Lambda實現它:
Calculator calc = (a, b) -> a + b;
System.out.println(calc.add(3, 5)); // 輸出 8
解釋:(a, b)對應add的參數,a + b是返回值,一行代碼完成接口實現。
總結:Lambda表達式的優勢¶
Lambda表達式讓代碼更簡潔、可讀性更高,尤其適合處理只有一個抽象方法的函數式接口。通過參數列表 -> 表達式體的語法,我們能用一行代碼替代冗長的匿名內部類,大幅減少模板代碼,讓邏輯更清晰。
掌握Lambda表達式後,你會發現處理線程、集合排序等場景變得異常簡單。後續學習中,還可以結合Java 8的Stream API等特性,進一步提升代碼效率!