1. 為什么使用Lambda表達式
Lambda是一個匿名函數,我們可以把Lambda表達式理解為是一段可以傳遞的代碼(將代碼像數據一樣進行傳遞)。可以寫出更簡潔、更靈活的代碼。作為一種更緊湊的代碼風格,使Java的語言表達能力得到了提升。
我們來看一下使用lambda之前創建匿名內部類:
1
2
3
4
5
6
|
new Thread( new Runnable() { @Override public void run() { System.out.println( "執行Runnable方法" ); } }); |
lambda表達式:
new Thread(() -> System.out.println("執行Runnable方法")); // 無參Lambda表達式
在Idea中遇到可以轉換lambda的代碼會有灰色提示,按alt+enter可自動轉換:
2. Lambda語法
Java8中引入了一個新的操作符"->”該操作符稱為箭頭操作符或Lambda 操作符。
箭頭操作符將Lambda表達式拆分成兩部分:
左側: Lambda表達式的參數列表
右側: Lambda表達式中所需執行的功能,即Lambda體
示例:
語法格式一:無參數,無返回值。
Runnable r = () -> System.out.println("Hello World");
r.run();
語法格式二:有一個參數,并且無返回值。
1
2
3
|
Consumer consumer = (x) -> System.out.println(x); //或者寫成: x -> System. out.println(x); 只有一個參數,括號可以省略 consumer.accept( "Hello" ); |
語法格式三:有兩個以上的參數,有返回值,并且Lambda體中有多條語句。
1
2
3
4
5
|
Comparator<Integer> comparator = (x, y) -> { System.out.println( "Hello" ); return Integer.compare(x, y); }; TreeSet<Integer> treeSet = new TreeSet<>(comparator); |
語法格式四:若Lambda體中只有一條語句,return 和大括號都可以省略不寫,Lambda 表達式的參數列表的數據類型可以省略不寫,因為JVM編譯器通過上下文推斷出數據類型,即類型推斷
Comparator<Integer> com = (x, y) -> Integer .compare(x, y);
關于類型推斷,其實在數組中我們早已經使用過:
1
2
3
4
5
6
|
String[] strArr = { "a" , "b" , "c" }; // 類型推斷 // 寫成下面這種方式則編譯報錯 String [] strArr; strArr = { "a" , "b" , "c" }; // 還有List的類型推斷: List<String> list = new ArrayList<>(); |
3. 函數式編程接口
上面我們看到的lambda表達式,其實都依賴于接口的支持,lambda表達式的本質是對接口的一種實現。這種接口稱為函數式接口,即接口中只有一個抽象方法的接口。函數式接口可以使用@FunctionInterface注解修飾,表示被修飾的接口必須是函數式接口。
1
2
3
4
5
|
// 函數式接口只能有一個抽象方法 @FunctionalInterface public interface FuncTest { void accept(Object o); } |
如果在函數式接口中寫兩個以上的方法,編譯會報錯:
我們來自己寫一個實際的例子了解下函數式接口的使用:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
// 1.寫一個對傳入參數進行操作的函數式接口 @FunctionalInterface public interface FuncTest { void operation(Integer x); } // 2.寫一個方法,將函數式,接口作為參數 private static Integer operate(Integer a, FuncTest funcTest) { return funcTest.operation(a); } // 3.使用函數式接口 System.out.println(operate( 1 , (x) -> x + x)); // 輸出 2 |
可以看到,我們在第3步才開始定義函數式接口的實際功能,對兩個數進行相加操作并返回結果。lambda的最大便捷之處就在于此,將代碼作為參數傳遞,非常靈活,大大精簡我們的代碼。
4. Java8內置的4種常用函數式接口
Consumer :消費型接口
方法:void accept(T t);
Consumer<String> consumer = x -> System.out.println(x);
consumer.accept("Hello"); // 打印Hello
Supplier :供給型接口
方法:T get();
Supplier<String> supplier = () -> "Hello";
System.out.println(supplier.get()); // 打印Hello
Function<T, R> :函數型接口
方法:R apply(T t);
Function function = x -> "Hello " + x;
System.out.println(function.apply("World"));
Predicate :斷言型接口
方法:boolean test(T t);
Predicate predicate = x -> x == "Hello";
System.out.println(predicate.test("Hello"));
ava.util.function 它包含了很多類,用來支持 Java的 函數式編程,該包中的函數式接口有:
5. 總結
Java8引入lambda表達式是接收了函數式編程語言的思想,例如scala之類的,它將函數視為一等公民,可以使用高階函數等。和指令式編程相比,函數式編程強調函數的計算比指令的執行重要。和過程化編程相比,函數式編程里函數的計算可隨時調用。
lambda表達式可以使代碼看起來簡潔,但一定程度上增加了代碼的可讀性以及調試的復雜性,所以在使用時應盡量是團隊都熟悉使用,要么干脆就別用,不然維護起來是件較痛苦的事。
以上這篇一文帶你徹底搞懂Lambda表達式就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持服務器之家。
原文鏈接:https://blog.csdn.net/xqnode/article/details/106966304