Java——Lambda表達式

1. 背景

Lambda表達式是JavaSE 8中一個重要的新特性。Lambda表達式允許你通過表達式來代替功能接口。 Lambda表達式就和方法一樣,它提供了一個正常的參數列表和一個使用這些參數的主體(body,可以是一個表達式或一個代碼塊)。 Lambda 表達式(Lambda expression),基于數學中的?λ?演算得名,也可稱為閉包(Closure)。

1.1 Lambda表達式的語法

基本語法: (parameters) -> expression 或 (parameters) ->{ statements; }

Lambda表達式由三部分組成:

1. paramaters:類似方法中的形參列表,這里的參數是函數式接口里的參數。這里的參數類型可以明確的聲明也可不聲明而由JVM隱含的推斷。另外當只有一個推斷類型時可以省略掉圓括號。

2. ->:可理解為“被用于”的意思

3. 方法體:可以是表達式也可以代碼塊,是函數式接口里方法的實現。代碼塊可返回一個值或者什么都不返回,這里的代碼塊等同于方法的方法體。如果是表達式,也可以返回一個值或者什么都不返回。

        // 1. 不需要參數,返回值為 2() -> 2// 2. 接收一個參數(數字類型),返回其2倍的值x -> 2 * x// 3. 接受2個參數(數字),并返回他們的和(x, y) -> x + y// 4. 接收2個int型整數,返回他們的乘積(int x, int y) -> x * y// 5. 接受一個 string 對象,并在控制臺打印,不返回任何值(看起來像是返回void)(String s) -> System.out.print(s)

1.2 函數式接口

要了解Lambda表達式,首先需要了解什么是函數式接口,函數式接口定義:一個接口有且只有一個抽象方法。

注意:

  1. 如果一個接口只有一個抽象方法,那么該接口就是一個函數式接口
  2. 如果我們在某個接口上聲明了 @FunctionalInterface 注解,那么編譯器就會按照函數式接口的定義來要求該接 口,這樣如果有兩個抽象方法,程序編譯就會報錯的。所以,從某種意義上來說,只要你保證你的接口中只有一個抽象方法,你可以不加這個注解。加上就會自動進行檢測。

定義方式:

        @FunctionalInterfaceinterface NoParameterNoReturn {//注意:只能有一個方法void test();}

特例:

        @FunctionalInterfaceinterface NoParameterNoReturn {void test();default void test2() {System.out.println("JDK1.8新特性,default默認方法可以有具體的實現");}}

2. Lambda表達式的基本使用

準備幾個接口:

//無返回值無參數
@FunctionalInterface
interface NoParameterNoReturn {void test();
}
//無返回值一個參數
@FunctionalInterface
interface OneParameterNoReturn {void test(int a);
}
//無返回值多個參數
@FunctionalInterface
interface MoreParameterNoReturn {void test(int a,int b);
}
//有返回值無參數
@FunctionalInterface
interface NoParameterReturn {int test();
}
//有返回值一個參數
@FunctionalInterface
interface OneParameterReturn {int test(int a);
}
//有返回值多參數
@FunctionalInterface
interface MoreParameterReturn {int test(int a,int b);
}

Lambda可以理解為:Lambda就是匿名內部類的簡化,實際上是創建了一個類,實現了接口,重寫了接口的方法。沒有使用Lambda表達式的時候的調用方式:

NoParameterNoReturn noParameterNoReturn = new NoParameterNoReturn(){@Overridepublic void test() {System.out.println("hello");}
};
noParameterNoReturn.test();

使用Lambda表達式:

public class TestDemo {public static void main(String[] args) {NoParameterNoReturn noParameterNoReturn = ()->System.out.println("無參數無返回值");noParameterNoReturn.test();OneParameterNoReturn oneParameterNoReturn = (int a)->System.out.println("一個參數無返回值:"+ a);oneParameterNoReturn.test(10);MoreParameterNoReturn moreParameterNoReturn = (int a,int b)->System.out.println("多個參數無返回值:"+a+" "+b);moreParameterNoReturn.test(20,30);//有返回值無參數!NoParameterReturn noParameterReturn = ()->10;System.out.println(noParameterReturn.test());//有返回值有一個參數!OneParameterReturn oneParameterReturn = a->a;oneParameterReturn.test(50);//有返回值多個參數!MoreParameterReturn moreParameterReturn = (a,b)->a+b;System.out.println(moreParameterReturn.test(60, 70));}
}

語法精簡tips:

  1. 參數類型可以省略,如果需要省略,每個參數的類型都要省略
  2. 參數的小括號里面只有一個參數,那么小括號可以省略
  3. 如果方法體當中只有一句代碼,那么大括號可以省略
  4. 如果方法體中只有一條語句,且是return語句,那么大括號可以省略,且去掉return關鍵字

3. 變量捕獲

?3.1 匿名內部類的變量捕獲

class Test {public void func(){System.out.println("func()");}
}
public class TestDemo {public static void main(String[] args) {int a = 100;new Test(){@Overridepublic void func() {System.out.println("我是內部類,且重寫了func這個方法!");System.out.println("我是捕獲到變量 a == "+a+" 我是一個常量,或者是一個沒有改變過值的變量!");}};}
}

在上述代碼當中的變量a就是,捕獲的變量。這個變量要么是被final修飾,如果不是被final修飾的 你要保證在使用 之前,沒有修改。如下代碼就是錯誤的代碼:

3.2 Lambda的變量捕獲

4. Lambda在集合中的使用

為了能夠讓Lambda和Java的集合類集更好的一起使用,集合當中也新增了部分接口,以便與Lambda表達式對接。

對應的接口

新增的方法

CollectionremoveIf() spliterator() stream() parallelStream() forEach()
ListreplaceAll() sort()
MapgetOrDefault() forEach() replaceAll() putIfAbsent() remove() replace() computeIfAbsent() computeIfPresent() compute() merge()

4.1?Collection接口

forEach()方法演示

該方法在接口 Iterable 當中,原型如下:

default void forEach(Consumer<? super T> action) {Objects.requireNonNull(action);for (T t : this) {action.accept(t);}
}

該方法表示:對容器中的每個元素執行action指定的動作

public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("Hello");list.add("world");list.add("hello");list.add("lambda");list.forEach(new Consumer<String>(){@Overridepublic void accept(String str){//簡單遍歷集合中的元素。System.out.print(str+" ");}});
}

輸出結果:Hello world hello lambda

我們可以修改為如下代碼:

public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("Hello");list.add("bit");list.add("hello");list.add("lambda");//表示調用一個,不帶有參數的方法,其執行花括號內的語句,為原來的函數體內容。list.forEach(s -> {System.out.println(s);});
}

輸出結果:Hello world hello lambda

4.2 List接口

sort()方法的演示

sort方法源碼:該方法根據c指定的比較規則對容器元素進行排序

public void sort(Comparator<? super E> c) {final int expectedModCount = modCount;Arrays.sort((E[]) elementData, 0, size, c);if (modCount != expectedModCount) {throw new ConcurrentModificationException();}modCount++;
}

使用示例:

public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("Hello");list.add("world");list.add("hello");list.add("lambda");list.sort(new Comparator<String>() {@Overridepublic int compare(String str1, String str2){//注意這里比較長度return str1.length()-str2.length();}});System.out.println(list);
}

輸出結果:Hello, world, hello, lambda

修改為Lambda表達式:

    public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("Hello");list.add("world");list.add("hello");list.add("lambda");
//調用帶有2個參數的方法,且返回長度的差值list.sort((str1,str2)-> str1.length()-str2.length());System.out.println(list);}

輸出結果:Hello, world, hello, lambda

4.3 Map接口

HashMap 的 forEach()

該方法原型如下:

default void forEach(BiConsumer<? super K, ? super V> action) {Objects.requireNonNull(action);for (Map.Entry<K, V> entry : entrySet()) {K k;V v;try {k = entry.getKey();v = entry.getValue();} catch(IllegalStateException ise) {// this usually means the entry is no longer in the map.throw new ConcurrentModificationException(ise);}action.accept(k, v);}
}

作用是對Map中的每個映射執行action指定的操作。

代碼示例:

    public static void main(String[] args) {HashMap<Integer, String> map = new HashMap<>();map.put(1, "hello");map.put(2, "world");map.put(3, "hello");map.put(4, "lambda");map.forEach(new BiConsumer<Integer, String>(){@Overridepublic void accept(Integer k, String v){System.out.print(k + "=" + v + " ");}});}

輸出結果: 1=hello 2=world 3=hello 4=lambda?

使用lambda表達式后的代碼:

    public static void main(String[] args) {HashMap<Integer, String> map = new HashMap<>();map.put(1, "hello");map.put(2, "world");map.put(3, "hello");map.put(4, "lambda");map.forEach((k,v)-> System.out.print(k + "=" + v + " "));}

輸出結果:1=hello 2=world 3=hello 4=lambda?

5. 總結

Lambda表達式的優點很明顯,在代碼層次上來說,使代碼變得非常的簡潔。缺點也很明顯,代碼不易讀。

優點:

  • 1. 代碼簡潔,開發迅速
  • 2. 方便函數式編程
  • 3. 非常容易進行并行計算
  • 4. Java 引入 Lambda,改善了集合操作

缺點:

  • 1. 代碼可讀性變差
  • 2. 在非并行計算中,很多計算未必有傳統的 for 性能要高
  • 3. 不容易進行調試

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/36482.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/36482.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/36482.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C# YoloV8 模型效果驗證工具(OnnxRuntime+ByteTrack推理)

C# YoloV8 模型效果驗證工具(OnnxRuntimeByteTrack推理) 目錄 效果 項目 代碼 下載 效果 模型效果驗證工具 項目 代碼 using ByteTrack; using OpenCvSharp; using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using Sys…

遠程服務器配置(堡壘機samba/ssh等)

分配了新的服務器后&#xff0c;要下載代碼首先要配置ssh。有以下兩種方式&#xff1a; 拷貝原本服務器的在本地的重新生成ssh&#xff0c;再跟服務器密鑰配對&#xff08;如未備份.gitconfig&#xff0c;還需重新配置git賬號郵箱。&#xff09; ssh配置 如果是拷貝過來的.ss…

【win11】Mouse without Borders安裝問題以管理員權限安裝msi文件

【win11】Mouse without Borders安裝問題&以管理員權限安裝msi文件 Mouse without Borders安裝問題解決&以管理員權限安裝msi文件啟動Windows Installer服務以管理員權限安裝msi文件 參考文獻 Mouse without Borders安裝問題 在win11下我雙擊MouseWithoutBorders2.2.1…

nodejs使用mysql模塊自動斷開

背景 第二天早上來的時候&#xff0c;發現接口返回異常Cannot enqueue Query after fatal error 從日志看上去&#xff0c;接口是正常運行的&#xff0c;搜索一下之后發現是數據庫的問題&#xff0c;連接斷開了 原因 MySQL中有一個名叫wait_timeout的變量&#xff0c;表示操…

由監官要求下架docker hub鏡像導致無法正常拉取鏡像

問題&#xff1a;下載docker鏡像超時 error pulling image configuration: download failed after attempts6: dial tcp 202.160.128.205:443: i/o timeout解決辦法&#xff1a;配置daemon.json [rootbogon aihuidi]# cat /etc/docker/daemon.json {"registry-mirrors&qu…

java springboot過濾器

在Spring Boot應用中添加自定義過濾器&#xff0c;可以通過實現Filter接口或繼承OncePerRequestFilter類來創建過濾器&#xff0c;并使用FilterRegistrationBean將其注冊到Spring容器中。 以下是一個簡單的示例&#xff1a; 1. 創建過濾器類 首先&#xff0c;創建一個實現Fil…

C++基礎語法:類構造函數

前言 "打牢基礎,萬事不愁" .C的基礎語法的學習 引入 類是實現面向對象思想的主要方法.前面提到:類是函數的變種,類可以通過調用靜態方法或者成員函數來實現邏輯.多數情況下使用成員函數.構造函數是生成類對象成員的必須條件,對此做一些構造函數的歸納 構造函數的目…

【日志消息類的編寫】

日志消息類編寫 由于上篇的代碼比較簡單&#xff0c;今天就多寫兩段代碼順便把日志消息類編寫完成。 這個類的實現就是&#xff1a;什么時間&#xff0c;哪個線程&#xff0c;哪個文件的哪一行&#xff0c;發生了什么等級的日志&#xff0c;日志機器名字是什么&#xff0c;日…

20240628 每日AI必讀資訊

&#x1f4da; Hugging Face 推出新版開源大模型排行榜&#xff0c;中國模型 Qwen-72B 奪冠 - 阿里Qwen-2-72B指令微調版本問鼎全球開源大模型排行榜榜首 - Llama-3-70B 微調版本排名第二&#xff0c;而 Mixtral-8x22B 微調版本位居第四。 - 另外&#xff0c;微軟的 Phi-3-M…

三種分布式鎖實現方式

目錄 1、數據庫自增 2、Redis自增 3、Zookeeper 4、其他 4.1、雪花算法 4.2、Tinyid 4.3、Leaf 4.4、數據庫號段 1、數據庫自增 利用數據庫表的自增特性&#xff0c;或主鍵唯一性&#xff0c;實現分布式ID REPLACE INTO id_table (stub) values (’a‘) ; SELECT LA…

社交App廣告優化新篇章:Xinstall引領用戶體驗升級,助力買量效果提升

隨著移動互聯網的快速發展&#xff0c;社交App已經成為人們生活中不可或缺的一部分。然而&#xff0c;在競爭激烈的市場環境下&#xff0c;如何有效地進行廣告投放&#xff0c;吸引并留住用戶&#xff0c;成為了每個社交App運營者面臨的重大挑戰。今天&#xff0c;我們就來談談…

自費5K,測評安德邁、小米、希喂三款寵物空氣凈化器誰才是高性價比之王

最近&#xff0c;家里的貓咪掉毛嚴重&#xff0c;簡直成了一個活生生的蒲公英&#xff0c;家中、空氣中各處都彌漫著貓浮毛甚至所有衣物都覆蓋著一層厚厚的貓毛。令人難以置信的是&#xff0c;有時我甚至在摳出的眼屎中都能發現夾雜著幾根貓毛。真的超級困擾了。但其實最空氣中…

Packer-Fuzzer一款好用的前端高效安全掃描工具

★★免責聲明★★ 文章中涉及的程序(方法)可能帶有攻擊性&#xff0c;僅供安全研究與學習之用&#xff0c;讀者將信息做其他用途&#xff0c;由Ta承擔全部法律及連帶責任&#xff0c;文章作者不承擔任何法律及連帶責任。 1、Packer Fuzzer介紹 Packer Fuzzer是一款針對Webpack…

4.if 條件判斷

1.if-else語句 if #判斷條件 :pass else:pass2.if - elif- else if #判斷條件 :pass elif #判斷條件:pass else:pass3.if語句可以嵌套 if #判斷條件 :passif #判斷條件 :pass 4.邏輯運算符 and 兩個都為真,才是真 or 一個為真 即是真 not 取反 and從左到右,所有值為真,返回…

麒麟系統安裝MySQL

搞了一整天&#xff0c;終于搞定了&#xff0c;記錄一下。 一、背景 項目的原因&#xff0c;基于JeecgBoot開發的系統需要國產化支持&#xff0c;這就需要在電腦上安裝MySQL等支撐軟件。 國產化項目的操作系統多是麒麟系統&#xff0c;我的系統如下&#xff1a; arm64架構。…

C#快速開發OPCUA服務器

為方便演示&#xff0c;此時創建一個控制臺應用程序。第三方dll(C編寫的庫opcsrv.dll&#xff0c;他人實現)。 拷貝dll到運行目錄下&#xff1a; 拷貝二次封裝后的文件到項目目錄下&#xff1a; 第一步&#xff1a;創建OpcUa服務器 //第一步&#xff1a;創建OpcUa服務器 OPCSr…

java.util.Optional類介紹

java.util.Optional 是 Java 8 引入的一個容器類,用于表示可能包含或不包含非空值的對象。它的設計初衷是為了減少程序中的空指針異常(NullPointerException),并使代碼更加簡潔和易讀。 Optional 類的介紹 1. 特點 避免顯式的 null 檢查:使用 Optional 可以避免顯式的 n…

基于ssh框架的個人博客源碼

基于ssh的個人博客源碼&#xff0c;頁面清爽簡潔&#xff0c;原先有部分bug,運行不了&#xff0c;現已修復 1.博客首頁 &#xff08;本地訪問地址 :localhost:8080/Blog/index/index&#xff09; 2.關于我 3.慢生活 4.留言板 5.我的相冊 微信掃碼下載源碼

商場配電新思維:智能網關驅動的自動化管理系統

在商場配電室監控系統中&#xff0c;主要是以無線網絡為載體&#xff0c;目的就是便于對變電站等實時監測與控制。其中&#xff0c;4G配電網關非常關鍵&#xff0c;可以將配電室系統終端上的信息數據及時上傳到服務器&#xff0c;再由服務器下達控制指令到各模塊中&#xff0c;…

Oracle Database 23ai新特性之INTERVAL聚合函數增強

Oracle Database 23ai 開始 AVG 以及 SUM 函數支持 INTERVAL 數據類型&#xff0c;它們可以作為聚合函數或者分析函數使用。 示例表 本文將會使用以下示例表&#xff1a; create table t1 (id integer,start_time timestamp,end_time timestamp,duration in…