您現在的位置是:首頁 > 足球

你有沒有掉進去過這些 Lambda 的 “陷阱”

  • 由 程式那點事 發表于 足球
  • 2022-09-29
簡介無引數 Lambda 表示式新建一個測試方法 testCreateThread,在建立一個 Runable 的執行緒需要在new Thread()的時候傳入 Runable 介面的匿名實現,寫法如下:@Testpublic void tes

派帕瑞斯陷阱怎麼過

一、Lambda 的正確使用姿勢

正確使用 Lambda 表示式

Lambda 表示式是 Java 8 的一個重要的新特性,Lambda 表示式可以允許透過表示式來代替功能介面,Lambda 表示式也可以

看作

是一個匿名函式,也可以成為閉包。

Lambda 的一個重要作用之一就是簡化匿名內部類的寫法,但是 Lambda 表示式不能替換所有的匿名內部類的書寫。

Lambda 表示式由三個部分組成,既

引數列表

->

方法體

引數列表

:方法中的形參列表,函式式接口裡的引數,如果沒有引數可以將括號省略。

->

:連線引數和方法的具體實現。

方法體

:既程式碼塊,具體的方法實現。

建立一個新的 Maven 專案 lambda-func-interfaces-traps,並新增 junit 依賴

junit junit 4。12 test

在 test 包下建立一個新的測試類 LambdaTest,用於演示無參和有參的 Lambda 表示式的寫法。

無引數 Lambda 表示式

新建一個測試方法 testCreateThread,在建立一個 Runable 的執行緒需要在

new Thread()

的時候傳入 Runable 介面的匿名實現,寫法如下:

@Testpublic void testCreateThread(){ new Thread(new Runnable() { @Override public void run() { System。out。println(“Thread Run !”); } })。start();}

執行上述測試程式碼,輸出結果如下:

Thread Run !

此時編輯器提示匿名類部分程式碼可以使用 Lambda 表示式來替換

你有沒有掉進去過這些 Lambda 的 “陷阱”

新增一個測試方法 testCreateThreadByLambda,使用 Lambda 表示式來代替匿名類。

@Testpublic void testCreateThreadByLambda(){ new Thread(() -> { System。out。println(“Thread Run which create by Lambda!”); })。start();}

執行上述程式碼,輸出結果如下:

Thread Run which create by Lambda!

使用 Lambda 表示式替換匿名類的寫法能夠正常執行程式,輸出

Thread run

。並且 Lambda 表示式的程式碼實現比較簡單的話可以省略

{}

將實現程式碼寫在一行內即可

有引數 Lambda 表示式

如果需要對集合物件或者陣列物件進行排序,那麼就需要實現 Comparator 介面,在介面的實現中定義比較的規則。

新增測試方法 testCompare,比較陣列物件

@Testpublic void testCompare(){ List stringList = Arrays。asList(“z”,“u”,“l”,“y”); Collections。sort(stringList, new Comparator(){ @Override public int compare(String o1, String o2) { if (o1 == null){ return -1; } if (o2 == null){ return 1; } return o1。length() - o2。length(); } });}

同樣在實現 Comparator 介面部分的程式碼,編輯器也提示可以使用 Lambda 來代替

建立新的測試方法 testCompareByLambdaWithParams

@Testpublic void testCompareByLambdaWithParams(){ List stringList = Arrays。asList(“z”,“u”,“l”,“y”); Collections。sort(stringList, (o1, o2) -> { if (o1 == null){ return -1; } if (o2 == null){ return 1; } return o1。length() - o2。length(); });}

上述程式碼中 Lambda 表示式的引數並沒有宣告引數型別,這是因為編輯器可以根據上下文推斷出變數的型別。

Lambda 表示式有哪些 “陷阱”

函式式介面的定義是一個介面有且只有一個抽象方法,但是函式式介面可以有多個非抽象方法

自定義函式式介面

首先在 com。traps。entity 包中定義一個 Hero 類

public class Hero { public String team; public String nickname; public String skill; public Hero(String team, String nickname, String skill) { this。team = team; this。nickname = nickname; this。skill = skill; } @Override public String toString() { return “Hero{” + “team=‘” + team + ’‘’ + “, nickname=‘” + nickname + ’‘’ + “, skill=‘” + skill + ’‘’ + ‘}’; }}

接著定義一個介面 InjectCompoundV,並使用 函式式介面的註解 @FunctionInterface 標註

@FunctionalInterfacepublic interface InjectCompoundV { // 透過注射五號化合物變成一個超級英雄 Hero transferToHomelander(String name);}

在測試包下建立一個函式式介面的測試類 InjectCompoundVTest

public class InjectCompoundVTest { public Map stringHeroMap = new HashMap<>(); @Before public void before(){ stringHeroMap。put(“Butcher”,new Hero(“The Seven”, “Homelander”, “Laser eyes”)); } @Test public void test(){ InjectCompoundV injectCompoundV = (name) -> stringHeroMap。get(name); System。out。println(injectCompoundV。transferToHomelander(“Butcher”)); }}

執行上測試程式碼,輸出結果如下:

Hero{team=‘The Seven’, nickname=‘Homelander’, skill=‘Laser eyes’}

Buthcher 透過呼叫函式式介面 InjectCompoundV 實現 transferToHomelander 方法變成了另一個 Homelander。

修改測試方法,使用方法引用的方式實現介面的匿名類

@Testpublic void test(){ InjectCompoundV injectCompoundV = stringHeroMap::get; System。out。println(injectCompoundV。transferToHomelander(“Butcher”));}

作者:黎曼假設

連結:https://juejin。cn/post/7113949902102593550

Top