對於任何場景而言,代碼量永遠都是越少越好,而Java8中提供的Lambda表達式正式簡化代碼的利器。
參考博客:Java 8 Lambda 表達式詳解
參考博客:完美的lambda表達式只有一行
在 Java 8 以前,若我們想要把某些功能傳遞給某些方法,總要去寫匿名類。
manager.addScheduleListener(new ScheduleListener() {
@Override
public void onSchedule(ScheduleEvent e) {
// Event listener implementation goes here...
}
});
Java 是面向對象語言,除了原始數據類型之處,Java 中的所有內容都是一個對象。而在函數式語言中,我們只需要給函數分配變量,並將這個函數作為參數傳遞給其它函數就可實現特定的功能。JavaScript 就是功能編程語言的典范(閉包)。也就是說Java中方法參數只有兩種:一是基礎數據類型,一是對象。為了兼容函數式編程,而出現了Lambda表達式。
什么是Lambda表達式
Java 中的 Lambda 表達式通常使用語法是 (argument) -> (body)
,比如:
(arg1, arg2...) -> { body }
(type1 arg1, type2 arg2...) -> { body }
如果Lambda表達式只有一行,則不需要{}
、return
、或者;
,比如:
(Integer e) -> e*2
再比如Lambda要創建一個比較器:
Comparator c = (p1, p2) -> p1.getAge().compareTo(p2.getAge());
甚至於:
Comparator c = Comparator.comparing(Person::getAge);
在這里的::
就是Java中的方法引用。
功能接口
在 Java 中,功能接口(Functional interface)指只有一個抽象方法的接口。
每個 Lambda 表達式都可以隱式地分配給功能接口。例如,我們可以從 Lambda 表達式創建 Runnable 接口的引用,如下所示:
Runnable r = () -> System.out.println("hello world");
編譯器會自動將上面的代碼編譯為:
new Thread(
() -> System.out.println("hello world")
).start();
Lambda 表達式的例子
線程初始化
// Old way
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hello world");
}
}).start();
// New way
new Thread(
() -> System.out.println("Hello world")
).start();
事件處理
// Old way
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Hello world");
}
});
// New way
button.addActionListener( (e) -> {
System.out.println("Hello world");
});
遍例輸出(方法引用)
// old way
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
for (Integer n : list) {
System.out.println(n);
}
// 使用 -> 的 Lambda 表達式
list.forEach(n -> System.out.println(n));
// 使用 :: 的 Lambda 表達式
list.forEach(System.out::println);
邏輯操作
package com.wuxianjiezh.demo.lambda;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
public class Main {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
System.out.print("輸出所有數字:");
evaluate(list, (n) -> true);
System.out.print("不輸出:");
evaluate(list, (n) -> false);
System.out.print("輸出偶數:");
evaluate(list, (n) -> n % 2 == 0);
System.out.print("輸出奇數:");
evaluate(list, (n) -> n % 2 == 1);
System.out.print("輸出大於 5 的數字:");
evaluate(list, (n) -> n > 5);
}
public static void evaluate(List<Integer> list, Predicate<Integer> predicate) {
for (Integer n : list) {
if (predicate.test(n)) {
System.out.print(n + " ");
}
}
System.out.println();
}
}
Stream API 示例
// old way
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
for(Integer n : list) {
int x = n * n;
System.out.println(x);
}
// new way
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
list.stream().map((x) -> x*x).forEach(System.out::println);