一文帶你看懂Java8中的lambda表達(dá)式和方法引用
上一篇文章介紹Consumer接口時(shí)講到lambda表達(dá)式和方法引用,這里順便將這兩個(gè)講一下。
Lambda 表達(dá)式是 Java 8 引入的一項(xiàng)重要特性,它提供了一種簡(jiǎn)潔、清晰且靈活的語(yǔ)法來(lái)表示可傳遞的匿名函數(shù)。Lambda 表達(dá)式是一種語(yǔ)法糖,提供了一種更簡(jiǎn)潔的語(yǔ)法來(lái)實(shí)例化函數(shù)式接口(Functional Interface)。
基本語(yǔ)法
Lambda 表達(dá)式的基本語(yǔ)法如下:
(parameters) -> expression
或
(parameters) -> { statements; }
其中:
parameters
指的是 Lambda 表達(dá)式的參數(shù)列表。->
是 Lambda 運(yùn)算符,它將參數(shù)列表與 Lambda 表達(dá)式的主體分開。expression
是 Lambda 表達(dá)式的返回表達(dá)式。{}
內(nèi)包含了 Lambda 表達(dá)式的代碼塊,可以包含多個(gè)語(yǔ)句。
示例
以下是一些 Lambda 表達(dá)式的示例:
不帶參數(shù)的 Lambda 表達(dá)式:
() -> System.out.println("Hello, Lambda!");
帶參數(shù)的 Lambda 表達(dá)式:
(int x, int y) -> x + y
帶參數(shù)和代碼塊的 Lambda 表達(dá)式:
(String s) -> { System.out.println(s); // 可以包含多個(gè)語(yǔ)句 }
使用場(chǎng)景
Lambda 表達(dá)式通常用于函數(shù)式接口的實(shí)例化,即接口中只有一個(gè)抽象方法的情況。例如,Runnable
、Callable
、Comparator
等接口都是函數(shù)式接口,可以通過(guò) Lambda 表達(dá)式來(lái)實(shí)例化。
// 使用 Lambda 表達(dá)式實(shí)例化 Runnable Runnable myRunnable = () -> System.out.println("Hello, Lambda!"); // 使用 Lambda 表達(dá)式實(shí)例化 Comparator Comparator<String> myComparator = (s1, s2) -> s1.compareTo(s2);
本質(zhì)
雖然 Lambda 表達(dá)式的語(yǔ)法看起來(lái)像是一個(gè)函數(shù),但實(shí)際上它在 Java 中被實(shí)現(xiàn)為一個(gè)對(duì)象,是一個(gè)匿名的內(nèi)部類對(duì)象。這個(gè)對(duì)象的類型是由編譯器根據(jù)上下文和目標(biāo)類型進(jìn)行推導(dǎo)的。這個(gè)對(duì)象可以被賦值給相應(yīng)的函數(shù)式接口。 在講Consumer接口時(shí),我們的一個(gè)例子。
import java.util.function.Consumer; public class ConsumerExample { public static void main(String[] args) { // 創(chuàng)建一個(gè)Consumer實(shí)例 Consumer<String> myConsumer = s -> System.out.println(s); // 使用Consumer的accept方法 myConsumer.accept("Hello, Consumer!"); } }
首先s -> System.out.println(s)
是lambda表達(dá)式,本質(zhì)是一個(gè)只含有一個(gè)方法的匿名內(nèi)部類對(duì)象。它的演化流程是,定義一個(gè)函數(shù)式接口
interface MyFunctionalInterface { void myMethod(String s); }
然后使用匿名內(nèi)部類(這個(gè)內(nèi)部類實(shí)現(xiàn)這個(gè)函數(shù)式接口,編寫抽象方法的邏輯),并實(shí)例化這個(gè)對(duì)象,由于java的多態(tài)特點(diǎn),父類引用可以指向子類對(duì)象,因此父類引用MyFunctionalInterface
可以指向新的接口實(shí)例化后的對(duì)象。
MyFunctionalInterface myFunction = new MyFunctionalInterface() { @Override public void myMethod(String s) { // 實(shí)現(xiàn)接口中的方法,比如 System.out.println(s); } };
這樣的寫法弊端是語(yǔ)法冗長(zhǎng),代碼顯得不夠簡(jiǎn)潔。Lambda 表達(dá)式的引入就是為了解決這個(gè)問(wèn)題,讓代碼更加緊湊和易讀。使用 Lambda 表達(dá)式,上面的代碼可以被簡(jiǎn)化為:
MyFunctionalInterface myFunction =(String s)-> System.out.println(s);
當(dāng) Lambda 表達(dá)式只有一個(gè)參數(shù)時(shí),可以省略參數(shù)的括號(hào)。而且當(dāng)上下文可以推斷出類型時(shí),參數(shù)的類型也可以省略。最終變?yōu)椋?/p>
Consumer<String> myConsumer = s -> System.out.println(s);
用java
泛型來(lái)推斷s
的類型為String
。
Consumer
本身就是一個(gè)函數(shù)式接口,所以此處System.out.println(s)
就是Consumer中抽象方法accept
的實(shí)現(xiàn)邏輯。示例中的MyFunctionalInterface
其實(shí)就是Consumer
,或者經(jīng)過(guò)編譯器推斷,這個(gè)函數(shù)式接口就是Consumer
。
方法引用
Lambda 表達(dá)式的一個(gè)變體是方法引用,它允許你直接引用已有的方法。例如:
// 使用靜態(tài)方法引用 Function<String, Integer> toInt = Integer::parseInt; // 使用實(shí)例方法引用 List<String> list = Arrays.asList("1", "2", "3"); list.forEach(System.out::println);
這里 Integer::parseInt
是一個(gè)靜態(tài)方法引用,System.out::println
是一個(gè)實(shí)例方法引用。
有四種主要的方法引用的形式:
靜態(tài)方法引用(Static Method Reference): ClassName::staticMethodName
實(shí)例方法引用(Instance Method Reference):
- 對(duì)于特定對(duì)象的實(shí)例方法:
instance::instanceMethodName
- 對(duì)于任意對(duì)象的實(shí)例方法:
ClassName::instanceMethodName
構(gòu)造方法引用(Constructor Reference): ClassName::new
數(shù)組構(gòu)造方法引用(Array Constructor Reference): TypeName[]::new
Lambda 表達(dá)式的優(yōu)勢(shì)
- 簡(jiǎn)潔性: Lambda 表達(dá)式可以減少冗余的代碼,使代碼更加簡(jiǎn)潔和易讀。
- 函數(shù)式編程: 提供了函數(shù)式編程的支持,使得在Java中更容易使用函數(shù)作為一等公民。
- 并行處理: 可以更容易地實(shí)現(xiàn)并行處理,通過(guò)并行流等特性,提高程序的性能。
Lambda 表達(dá)式是 Java 8 引入的一項(xiàng)重要特性,它在編寫簡(jiǎn)潔、清晰的代碼和支持函數(shù)式編程方面起到了關(guān)鍵作用。方法引用是Lambda 表達(dá)式的變體。
以上就是一文帶你看懂Java8中的lambda表達(dá)式和方法引用的詳細(xì)內(nèi)容,更多關(guān)于Java8 lambda表達(dá)式的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- Java8新特性-Lambda表達(dá)式詳解
- java8新特性-lambda表達(dá)式入門學(xué)習(xí)心得
- java8中的lambda表達(dá)式簡(jiǎn)介
- Java8?lambda表達(dá)式的10個(gè)實(shí)例講解
- 詳解Java8如何使用Lambda表達(dá)式進(jìn)行比較
- Java8新特性:lambda表達(dá)式總結(jié)
- java8 forEach結(jié)合Lambda表達(dá)式遍歷 List操作
- Java8 用Lambda表達(dá)式給List集合排序的實(shí)現(xiàn)
- Java8中的Lambda表達(dá)式理解與使用示例詳解
相關(guān)文章
SpringBoot實(shí)現(xiàn)kafka多源配置的示例代碼
實(shí)際開發(fā)中,不同的topic可能來(lái)自不同的集群,所以就需要配置不同的kafka數(shù)據(jù)源,基于springboot自動(dòng)配置的思想,最終通過(guò)配置文件的配置,自動(dòng)生成生產(chǎn)者及消費(fèi)者的配置,本文介紹了SpringBoot實(shí)現(xiàn)kafka多源配置,需要的朋友可以參考下2024-06-06Java 添加、刪除、替換、格式化Word中的文本的步驟詳解(基于Spire.Cloud.SDK for Java)
這篇文章主要介紹了Java 添加、刪除、替換、格式化Word中的文本(基于Spire.Cloud.SDK for Java),本文分步驟通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08SpringSecurity整合springBoot、redis實(shí)現(xiàn)登錄互踢功能
這篇文章主要介紹了SpringSecurity整合springBoot、redis實(shí)現(xiàn)登錄互踢,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-05-05SpringBoot入門實(shí)現(xiàn)第一個(gè)SpringBoot項(xiàng)目
今天我們一起來(lái)完成一個(gè)簡(jiǎn)單的SpringBoot(Hello World)。就把他作為你的第一個(gè)SpringBoot項(xiàng)目。具有一定的參考價(jià)值,感興趣的可以了解一下2021-09-09java定長(zhǎng)隊(duì)列的實(shí)現(xiàn)示例
定長(zhǎng)隊(duì)列是一種有限容量的隊(duì)列,對(duì)于某些應(yīng)用場(chǎng)景非常有用,本文主要介紹了java定長(zhǎng)隊(duì)列的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下2024-02-02JVM解密之解構(gòu)類加載與GC垃圾回收機(jī)制詳解
本文主要介紹了Java虛擬機(jī)(JVM)的內(nèi)存劃分、類加載機(jī)制以及垃圾回收機(jī)制,JVM的內(nèi)存劃分為程序計(jì)數(shù)器、棧、堆和方法區(qū),類加載機(jī)制包括類加載過(guò)程、加載器模型和雙親委派模型,垃圾回收機(jī)制主要包括標(biāo)記-清除、標(biāo)記-復(fù)制、標(biāo)記-整理和分代回收算法2025-02-02Springboot項(xiàng)目與vue項(xiàng)目整合打包的實(shí)現(xiàn)方式
這篇文章主要介紹了Springboot項(xiàng)目與vue項(xiàng)目整合打包的實(shí)現(xiàn)方式,本文通過(guò)兩種方式給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-07-07