一文帶你徹底搞懂Lambda表示式
1. 為什麼使用Lambda表示式
Lambda是一個匿名函式,我們可以把Lambda表示式理解為是一段可以傳遞的程式碼(將程式碼像資料一樣進行傳遞)。可以寫出更簡潔、更靈活的程式碼。作為一種更緊湊的程式碼風格,使Java的語言表達能力得到了提升。
我們來看一下使用lambda之前建立匿名內部類:
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();
語法格式二:有一個引數,並且無返回值。
Consumer consumer = (x) -> System.out.println(x); //或者寫成: x -> System. out.println(x); 只有一個引數,括號可以省略 consumer.accept("Hello");
語法格式三:有兩個以上的引數,有返回值,並且Lambda體中有多條語句。
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);
關於型別推斷,其實在陣列中我們早已經使用過:
String[] strArr = {"a","b","c"}; // 型別推斷 // 寫成下面這種方式則編譯報錯 String [] strArr; strArr = {"a","c"}; // 還有List的型別推斷: List<String> list = new ArrayList<>();
3. 函數語言程式設計介面
上面我們看到的lambda表示式,其實都依賴於介面的支援,lambda表示式的本質是對介面的一種實現。這種介面稱為函式式介面,即介面中只有一個抽象方法的介面。函式式介面可以使用@FunctionInterface註解修飾,表示被修飾的介面必須是函式式介面。
// 函式式介面只能有一個抽象方法 @FunctionalInterface public interface FuncTest { void accept(Object o); }
如果在函式式介面中寫兩個以上的方法,編譯會報錯:
我們來自己寫一個實際的例子瞭解下函式式介面的使用:
// 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表示式就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。