一、說明
Jdk1.8最重要的特性即Lambda表達式。它允許把一個函數作爲參數傳遞進方法中,簡化了匿名實現類的書寫
Lambda 表達式需要 函數式接口 的支持,即把只有一個抽象方法的接口的匿名實現,以方法參數在左,方法實現在右的形式構建,並將其作爲參數傳進方法中
Lambda表達式引入了一個新的操作符 "->",它將Lambda分爲兩個部分:
/**
* 左側:指定了Lambda表達式所需要的所有參數
* 右側:指定了Lambda表達式所要執行的代碼塊
*/
(參數類型 參數名, 參數類型 參數名...) -> {
代碼塊,即方法體
};
二、示例
- 1、線程
// SE8 之前
Thread thread = new Thread(new Runnable() {
public void run() {
System.out.println("hello world");
}
});
thread.start();
// SE8 開始
Runnable runnable = () -> System.out.println("run ...");
Thread thread = new Thread(runnable);
thread.start();
// SE8 簡寫
new Thread(() -> System.out.println("run ...")).start();
- 2、排序
List<String> strs = new ArrayList<String>();
// SE8 之前
Collections.sort(strs, new Comparator<String>() {
public int compare(String str1, String str2) {
return str1.compareTo(str2);
}
});
// SE8 開始
Collections.sort(strs, (str1, str2) -> str1.compareTo(str2));
- 3、自定義
@FunctionalInterface
public interface ExecInterface {
public void execute(String a, String b);
}
// SE8之前
ExecInterface execOri = new ExecInterface() {
@Override
public void execute(String a, String b) {
System.out.println(a + b);
}
};
execOri.execute("aaaa", "bbbb");
// SE8開始
ExecInterface execLam = (a, b) -> System.out.println(a + b);
execLam.execute("aaaa", "bbbb");
三、語法
- 1、完整語法
// 函數式接口方法
public void execute(String a, String b);
// Lambda表達式
ExecInterface execLam = (String a, String b) -> {System.out.println(a + b);};
- 2、參數類型可以省略 (類型推斷:因爲接口中只有一個抽象方法,知道方法即可推出參數及其類型)
// 函數式接口方法
public void execute(String a, String b);
// Lambda表達式
ExecInterface execLam = ( a, b) -> {System.out.println(a + b);};
- 3、當參數個數只有一個時,也可以省略()
//函數式接口方法
public void execute(String a);
//Lambda表達式
ExecInterface execLam = a -> { System.out.println(a); };
- 4、當方法體中只有一行代碼時,可以省略{}
//函數式接口方法
public void execute(String a);
//Lambda表達式
ExecInterface execLam = a -> System.out.println(a);
- 5、當方法體中只有一行代碼並且需要返回值時,也可以省略掉return
// 函數式接口方法
public String execute(String a);
// Lambda表達式
ExecInterface execLam = a -> a + "hello";
- 6、當表達式沒有參數時,一對小括號是不能省略掉的
// 函數式接口方法
public void execute();
// Lambda表達式
ExecInterface execLam = () -> System.out.println("Hello");
四、常用
Java8 內置了大量函數式接口,位於java.util.function包中,通常情況下不需要再自定義接口
- 1、Supplier<T> :供應商;沒有參數,有返回值
Supplier<String> supplier = () -> "Hello!";
System.out.println(supplier.get());
- 2、Consumer<T> :消費者;只有一個參數,沒有返回值
Consumer<String> consumer = (name) -> System.out.println(name + ": " + "Hello!");
consumer.accept("Xlien");
- 3、Function<T, R> :函數;一個參數,一個返回值
Function<String, String> func = (name) -> name + ": " + "Hello!";
System.out.println(func.apply("Xlien"));
- 4、BiFunction<T, U, R> :二元函數;兩個參數,一個返回值
BiFunction<String, String, String> biFunc = (String name, String msg) -> {
String str = name + "," + msg + "!";
return str;
};
System.out.println(biFunc.apply("Xlien", "Hello!"));
- 5、Comparator<T> :比較器;接收兩個參數,返回比較的結果
Comparator<String> comparator = (s1, s2) -> s1.compareTo(s2);
System.out.println(comparator.compare("abc", "abd"));
- 6、Predicate<T> :斷言;用於測試一個條件的真假
Predicate<String> predicate = (str) -> str.length() < 20;
// 即
Predicate<String> predicate = new Predicate<String>() {
@Override
public boolean test(String str) {
return str.length() < 20;
}
};
System.out.println(predicate.test("[email protected]")); // 判斷真假
System.out.println(predicate.negate().test("[email protected]")); // 邏輯否的判斷真假
System.out.println(predicate.and((str) -> str.length() > 10).test("abcdefg")); // 組合判斷 length<20 AND length > 10
System.out.println(Predicate.isEqual("aaaa").test("aaaa")); // 判斷是否相等(equal)