一文帶你徹底搞懂Lambda表達式
1. 為什么使用Lambda表達式
Lambda是一個匿名函數(shù),我們可以把Lambda表達式理解為是一段可以傳遞的代碼(將代碼像數(shù)據(jù)一樣進行傳遞)??梢詫懗龈啙?、更靈活的代碼。作為一種更緊湊的代碼風格,使Java的語言表達能力得到了提升。
我們來看一下使用lambda之前創(chuàng)建匿名內(nèi)部類:
new Thread(new Runnable() { @Override public void run() { System.out.println("執(zhí)行Runnable方法"); } });
lambda表達式:
new Thread(() -> System.out.println("執(zhí)行Runnable方法")); // 無參Lambda表達式
在Idea中遇到可以轉(zhuǎn)換lambda的代碼會有灰色提示,按alt+enter可自動轉(zhuǎn)換:
2. Lambda語法
Java8中引入了一個新的操作符"->”該操作符稱為箭頭操作符或Lambda 操作符。
箭頭操作符將Lambda表達式拆分成兩部分:
左側(cè): Lambda表達式的參數(shù)列表
右側(cè): Lambda表達式中所需執(zhí)行的功能,即Lambda體
示例:
語法格式一:無參數(shù),無返回值。
Runnable r = () -> System.out.println("Hello World");
r.run();
語法格式二:有一個參數(shù),并且無返回值。
Consumer consumer = (x) -> System.out.println(x); //或者寫成: x -> System. out.println(x); 只有一個參數(shù),括號可以省略 consumer.accept("Hello");
語法格式三:有兩個以上的參數(shù),有返回值,并且Lambda體中有多條語句。
Comparator<Integer> comparator = (x, y) -> { System.out.println("Hello"); return Integer.compare(x, y); }; TreeSet<Integer> treeSet = new TreeSet<>(comparator);
語法格式四:若Lambda體中只有一條語句,return 和大括號都可以省略不寫,Lambda 表達式的參數(shù)列表的數(shù)據(jù)類型可以省略不寫,因為JVM編譯器通過上下文推斷出數(shù)據(jù)類型,即類型推斷
Comparator<Integer> com = (x, y) -> Integer .compare(x, y);
關(guān)于類型推斷,其實在數(shù)組中我們早已經(jīng)使用過:
String[] strArr = {"a","b", "c"}; // 類型推斷 // 寫成下面這種方式則編譯報錯 String [] strArr; strArr = {"a","b", "c"}; // 還有List的類型推斷: List<String> list = new ArrayList<>();
3. 函數(shù)式編程接口
上面我們看到的lambda表達式,其實都依賴于接口的支持,lambda表達式的本質(zhì)是對接口的一種實現(xiàn)。這種接口稱為函數(shù)式接口,即接口中只有一個抽象方法的接口。函數(shù)式接口可以使用@FunctionInterface注解修飾,表示被修飾的接口必須是函數(shù)式接口。
// 函數(shù)式接口只能有一個抽象方法 @FunctionalInterface public interface FuncTest { void accept(Object o); }
如果在函數(shù)式接口中寫兩個以上的方法,編譯會報錯:
我們來自己寫一個實際的例子了解下函數(shù)式接口的使用:
// 1.寫一個對傳入?yún)?shù)進行操作的函數(shù)式接口 @FunctionalInterface public interface FuncTest { void operation(Integer x); } // 2.寫一個方法,將函數(shù)式,接口作為參數(shù) private static Integer operate(Integer a, FuncTest funcTest) { return funcTest.operation(a); } // 3.使用函數(shù)式接口 System.out.println(operate(1, (x) -> x + x)); // 輸出 2
可以看到,我們在第3步才開始定義函數(shù)式接口的實際功能,對兩個數(shù)進行相加操作并返回結(jié)果。lambda的最大便捷之處就在于此,將代碼作為參數(shù)傳遞,非常靈活,大大精簡我們的代碼。
4. Java8內(nèi)置的4種常用函數(shù)式接口
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> :函數(shù)型接口
方法: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的 函數(shù)式編程,該包中的函數(shù)式接口有:
5. 總結(jié)
Java8引入lambda表達式是接收了函數(shù)式編程語言的思想,例如scala之類的,它將函數(shù)視為一等公民,可以使用高階函數(shù)等。和指令式編程相比,函數(shù)式編程強調(diào)函數(shù)的計算比指令的執(zhí)行重要。和過程化編程相比,函數(shù)式編程里函數(shù)的計算可隨時調(diào)用。
lambda表達式可以使代碼看起來簡潔,但一定程度上增加了代碼的可讀性以及調(diào)試的復雜性,所以在使用時應(yīng)盡量是團隊都熟悉使用,要么干脆就別用,不然維護起來是件較痛苦的事。
以上這篇一文帶你徹底搞懂Lambda表達式就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringMVC @RequestBody Date類型的Json轉(zhuǎn)換方式
這篇文章主要介紹了SpringMVC @RequestBody Date類型的Json轉(zhuǎn)換方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10Java實現(xiàn)發(fā)送手機短信語音驗證功能代碼實例
這篇文章主要介紹了Java實現(xiàn)發(fā)送手機短信語音驗證功能代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2019-09-09Elasticsearch?mapping?概念及自動創(chuàng)建示例
這篇文章主要為大家介紹了Elasticsearch?mapping?概念及自動創(chuàng)建示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-11-11ThreadPoolExecutor中的submit()方法詳細講解
在使用線程池的時候,發(fā)現(xiàn)除了execute()方法可以執(zhí)行任務(wù)外,還發(fā)現(xiàn)有一個方法submit()可以執(zhí)行任務(wù),本文就詳細的介紹一下ThreadPoolExecutor中的submit()方法,具有一定的參考價值,感興趣的可以了解一下2022-04-04idea2020.2卡死在reading maven projects
這篇文章主要介紹了idea2020.2卡死在reading maven projects,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-09-09Java 高并發(fā)七:并發(fā)設(shè)計模型詳解
本文主要介紹Java高并發(fā) 并發(fā)設(shè)計模型的知識,這里主要講解 1. 什么是設(shè)計模式 2. 單例模式 3. 不變模式 4. Future模式 5. 生產(chǎn)者消費者,有需要的小伙伴可以參考下2016-09-09