精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

高效開發!Lambda表達式和函數式接口最佳實踐

開發 前端
在 java.util.function 包中定義的函數式接口滿足了大多數開發者為 lambda 表達式和方法引用提供目標類型的需求。這些接口中的每一個都是通用且抽象的,這使得它們能夠輕松適應幾乎任何 lambda 表達式。

環境:Spring Boot 3.2.5

1. 簡介

Lambda表達式與函數式接口是Java 8引入的重要特性,它們極大地簡化了代碼編寫,提升了代碼的可讀性和簡潔性。Lambda表達式提供了一種簡潔的方式來表示匿名函數,而函數式接口則是一種只包含一個抽象方法的接口,非常適合與Lambda表達式結合使用。

在實際開發中,合理運用這些特性可以提高代碼的靈活性和復用性。最佳實踐中,推薦首先定義清晰且具有描述性的函數式接口,以增強代碼的可理解性;其次,在使用Lambda表達式時,盡量保持其簡短且功能單一,避免復雜的邏輯嵌套;此外,利用Stream API等函數式編程工具進行集合操作,能夠使代碼更加流暢、高效。通過遵循這些原則,開發者不僅能夠寫出更加優雅的代碼,還能更好地應對并發編程的需求,提升程序的整體性能。

接下來,我們將詳細研究函 數式接口 和 lambda 表達式。

2. 最佳實踐

2.1 優先使用標準的函數式接口

在 java.util.function 包中定義的函數式接口滿足了大多數開發者為 lambda 表達式和方法引用提供目標類型的需求。這些接口中的每一個都是通用且抽象的,這使得它們能夠輕松適應幾乎任何 lambda 表達式。我們在創建自定義的函數式接口之前,應該優先查看該包中的定義。

我們先來看下如下接口:

@FunctionalInterface
public interface Foo {


  String xxxooo(String string) ;
}

實用該接口:

public class UseFoo {
  public String pack(String param, Foo foo) {
    return foo.xxxooo(param) ;
  }
}

運行程序應該是如下方式:

Foo foo = param -> String.format("%s other info", param) ;
String ret = new UseFoo().pack("Message ", foo) ;

在這里的Foo接口方法簽名需要一個入參然后返回一個參數。而Java 8 已經在 java.util.function 包中提供了這樣的接口 Function<T, R>。所以我們沒有必要自己在定義,可以將上面的UseFoo修改如下:

public String pack(String param, Function<String, String> foo) {
  return foo.apply(param) ;
}
// 調用
Function<String, String> foo = param -> String.format("%s other info", param) ;

使用與之前定義的基本相同。

2.2 使用@FunctionalInterface注解

使用 @FunctionalInterface 注解接口。乍一看,這個注解似乎沒有什么用處。即使沒有它,只要接口中只有一個抽象方法,該接口也會被視為函數式接口。

然而,如果在一個大型項目中有多個接口;手動控制所有接口是很困難的。一個原本設計為函數式的接口可能會因為不小心添加了另一個抽象方法而被改變,從而使它不再是一個有效的函數式接口。

通過使用 @FunctionalInterface 注解,編譯器會在任何試圖破壞函數式接口預定義結構的行為時觸發錯誤。如下示例:

@FunctionalInterface
public interface Foo {
  String xxxooo(String param) ;
}

使用該接口,能防止你再定義其它方法。

2.3 不要在函數式接口中過渡使用默認方法

我們可以輕松地在函數式接口中添加默認方法。只要接口中只有一個抽象方法聲明,這樣做是符合函數式接口契約的:

@FunctionalInterface
public interface Foo {
  String xxxooo(String param);
  default void defaultMethod() {
    // ...
  }
}

如果它們的抽象方法具有相同的簽名,函數式接口可以被其他函數式接口繼承:

@FunctionalInterface
public interface Zoo extends Baz, Bar {}
  
@FunctionalInterface
public interface Baz {  
  String xxxooo(String param);  
  default String defaultBaz() {
    return "Baz..." ;
  }    
}
  
@FunctionalInterface
public interface Bar {  
  String xxxooo(String param);  
  default String defaultBar() {
    return "Bar..." ;
  }  
}
public static void main(String[] args) {
  Zoo zoo = param -> String.format("%s extends", param) ;
  System.out.println(zoo.xxxooo("Functional Interface")) ;
}

就像普通的接口一樣,如果不同的函數式接口繼承了具有相同默認方法的接口,這也可能會帶來問題。

修改上面的Baz和Bar接口,添加相同的默認方法:

@FunctionalInterface
public interface Baz { 
  default String print(){
    // ...
  }
}
@FunctionalInterface
public interface Bar { 
  default String print(){
    // ...
  }
}

這樣定義后,Zoo接口將編譯不通過,重復的默認方法錯誤。

我們可以通過如下方式,在Zoo接口重寫defaultCommon方法,如下示例:

@FunctionalInterface
public interface Zoo extends Baz, Bar {
  @Override
  default String print() {
    return Bar.super.print() ;
  }
}

所以,我們不應該在函數式接口中定義過多的默認方法。

2.4 使用 Lambda 表達式實例化功能接口

編譯器允許我們使用內部類來實例化函數式接口;然而,這樣做會導致代碼非常冗長。我們應該優先使用 lambda 表達式:

// 是使用上面定義的Zoo接口
Zoo zoo = param -> String.format("%s extends", param) ;
System.out.println(zoo.xxxooo("Functional Interface")) ;

如果是內部類定義那就太不優雅了。

Zoo zoo = new Zoo() {
  public String xxxooo(String param) {
    return String.format("%s extends", param) ;
  }
} ;

現在開發工具都能自動幫你將這里的內部類轉換為lambda表達式。

2.5 避免重載帶有函數式接口作為參數的方法

public interface Processor {
  String process(Callable<String> c) throws Exception;


  String process(Supplier<String> s);
}


public class ProcessorImpl implements Processor {
  public String process(Callable<String> c) throws Exception {
    return c.call() ;
  }
  public String process(Supplier<String> s) {
    return s.get() ;
  }
}

上面代碼看著沒撒毛病,但是你通過lambda表達傳參時,就出問題了:

ProcessorImpl process = new ProcessorImpl() ;
process.process(() -> "Pack") ;

Eclipse下提示

圖片圖片

模棱兩可的方法調用。解決辦法有2種:

  • 定義不同的方法名稱
  • 強制轉換
ProcessorImpl process = new ProcessorImpl() ;
process.process((Supplier<String>)() -> "Pack") ;

但是不推薦這種方式。

2.6 不要將 Lambda 表達式視為內部類

盡管在前面的例子中,我們基本上是用 Lambda 表達式替換了內部類,但這兩個概念在一個重要方面是不同的:作用域。

當我們使用內部類時,它會創建一個新的作用域。我們可以通過實例化具有相同名稱的新局部變量來隱藏外部作用域中的局部變量。我們還可以在內部類中使用 this 關鍵字作為對其自身實例的引用。

然而,Lambda 表達式則與外部作用域一起工作。我們不能在 Lambda 表達式的主體中隱藏外部作用域中的變量。在這種情況下,this 關鍵字是對外部實例的引用。

private String value = "Outer class value";


@FunctionalInterface
public interface Foo {
  String fn(String param);
}


public void xxoo() {
  Foo f = new Foo() {
    String value = "Inner class value";


    @Override
    public String fn(String param) {
      return this.value;
    }
  };
  String ret = f.fn("Pack") ;
  System.out.println(ret) ;
  Foo fl = param -> {
    String value = "Lambda value";
    return this.value;
  };
  ret = fl.fn("Pack");


  System.out.println(ret) ;
}

輸出結果:

Inner class value
Outer class value

根據運行結果得知,在Lambda中this.value方法的是類中定義的變量,而內部類訪問的則是當前內部類的變量。

2.7 避免在 Lambda 表達式的主體中使用代碼塊

Lambda 表達式應該用一行代碼來編寫。通過這種方式,Lambda 表達式成為一個自解釋的結構,聲明了應該對哪些數據執行什么操作。

如果我們有一大段代碼,那么 lambda 的功能就不會立即顯現出來。

Foo foo = param -> buildString(param) ;
private String buildString(String param) {
  String result = "Something " + param ;
  // ...
  return result ;
}

而不應該是如下代碼

Foo foo = param -> { 
  String result = "Something " + param ; 
  // ...
  return result ; 
} ;

注意:如果 lambda的定義有兩三行代碼,那么將代碼提取到另一個方法中也沒有什么價值,我們不應該將 "單行 lambda" 完全作為一個規約。

2.8 避免指定參數類型

在大多數情況下,編譯器可以通過類型推斷來確定 lambda 參數的類型。 因此,為參數添加類型是可選的,可以省略,如下實例:

BiFunction<String, String, String> fun = 
  (String a, String b) -> a.toLowerCase() + b.toLowerCase() ;

這里我們不用聲明類型,而是如下方式:

BiFunction<String, String, String> fun = 
  (a, b) -> a.toLowerCase() + b.toLowerCase() ;

這里完全可以通過類型推斷確定類型,所以沒有必要什么參數的類型。

2.9 單參數不要使用括號

Lambda 語法只要求在多個參數或沒有參數時使用括號。

錯誤示例

Function<String, String> fun = (a) -> a.toLowerCase() ;

正確示例

Function<String, String> fun = a -> a.toLowerCase() ;

只有一個參數時沒有必要添加括號

2.10 避免返回語句和括號

理想情況下,Lambda 表達式應該用一行代碼來編寫。通過這種方式,Lambda 表達式成為一個自解釋的結構,聲明了應該對哪些數據執行什么操作。

錯誤示例

Function<String, String> func = a -> {return a.toLowerCase()};

正確示例

Function<String, String> func = a -> a.toLowerCase() ;

這里我們沒有必要使用代碼塊,我們應該時刻注意盡可能的使得 Lambda 表達式只有一行。

2.11 方法引用

很多時候,即使在我們之前的示例中,lambda 表達式也只是調用其他地方已經實現的方法。 在這種情況下,使用 Java 8 的另一個特性--方法引用就非常有用了。

錯誤示例

Function<String, String> func = a -> a.toLowerCase();

正確示例

Function<String, String> func = String::toLowerCase;

如果你不懂方法引用,那么這種寫法是不是可讀性不好了?

2.12 使用"Effectively Final"變量

在 Lambda 表達式內部訪問 非final 變量會導致編譯時錯誤,但這并不意味著我們應該將每個目標變量都標記為 final。根據 "Effectively final" 的概念,只要變量僅被賦值一次,編譯器就會將其視為 final。

public void xxxooo() {
  String value = "Local" ; // 這里我們可以省去 final 修飾符
  Function<String, String> func = str -> {
    return value ;
  } ;
}

這里我們沒有必要在變量value前使用 final 修飾。但是我們不能在代碼塊中去修改,如下將無法編譯通過:

圖片 圖片

責任編輯:武曉燕 來源: Spring全家桶實戰案例源碼
相關推薦

2022-12-05 09:31:51

接口lambda表達式

2024-03-08 09:45:21

Lambda表達式Stream

2020-10-16 10:07:03

Lambda表達式Java8

2022-12-01 07:38:49

lambda表達式函數式

2009-08-10 10:06:10

.NET Lambda

2009-08-31 17:11:37

Lambda表達式

2009-09-17 09:09:50

Lambda表達式Linq查詢

2021-08-31 07:19:41

Lambda表達式C#

2020-10-16 06:40:25

C++匿名函數

2009-09-15 15:18:00

Linq Lambda

2009-09-09 13:01:33

LINQ Lambda

2009-09-11 09:48:27

Linq Lambda

2009-08-10 17:11:34

.NET 3.5擴展方Lambda表達式

2009-10-12 10:11:08

Lambda表達式編寫

2024-03-12 08:23:54

JavaLambda函數式編程

2009-09-17 09:44:54

Linq Lambda

2009-09-17 10:40:22

Linq Lambda

2009-09-15 17:30:00

Linq Lambda

2009-08-27 09:44:59

C# Lambda表達

2012-06-26 10:03:58

JavaJava 8lambda
點贊
收藏

51CTO技術棧公眾號

国产精品久久久久av蜜臀| 麻豆传媒在线免费看| 久久精品九九| 中文字幕综合在线| 综合激情成人伊人| 日产精品99久久久久久| 自拍偷拍第9页| 中文字幕一区二区三区四区久久| 午夜精品福利视频网站| 欧美一区二区综合| 99热这里只有精品在线观看| 亚洲影视综合| 久久这里只有精品99| 国产精品伦子伦| 91精品一久久香蕉国产线看观看 | 人妖欧美1区| xfplay精品久久| 91久久精品一区二区别| 中文字幕一区二区人妻电影| 一区二区免费不卡在线| 亚洲欧美制服第一页| 韩国三级在线看| 国产精品无码久久久久| 舔着乳尖日韩一区| 国产精品jizz在线观看老狼| 日韩在线免费播放| 国产成人精品免费视频网站| 国产精品一区二区三区毛片淫片| 日本网站免费观看| 亚洲一区二区三区无吗| 亚洲天天在线日亚洲洲精| 性折磨bdsm欧美激情另类| 国产91亚洲精品久久久| 欧美体内谢she精2性欧美| 国产又粗又猛又爽又黄的网站| jzzjzzjzz亚洲成熟少妇| www.在线欧美| 国产精品乱子乱xxxx| 一区二区三区精彩视频| 三级成人在线视频| 欧美亚洲在线视频| 久久精品国产亚洲AV无码麻豆| 国产精品久久久久久久免费观看 | 欧美大波大乳巨大乳| 精品精品视频| 538在线一区二区精品国产| 国产视频在线视频| 黄色亚洲网站| 欧美日韩中文在线观看| 国产免费黄色一级片| 日本一级理论片在线大全| 亚洲色图欧美在线| 宅男在线精品国产免费观看| 91大神xh98hx在线播放| 国产欧美一区二区在线| 欧美日韩一区在线视频| 免费人成黄页在线观看忧物| 91视频精品在这里| 麻豆成人av| 毛片网站在线观看| 久久久.com| 天堂精品一区二区三区| 国产高清视频免费最新在线| 国产蜜臀av在线一区二区三区| 日本欧美色综合网站免费| 精品美女视频在线观看免费软件| 国产欧美精品区一区二区三区 | 国产人妖伪娘一区91| 正在播放木下凛凛xv99| 免费在线观看日韩欧美| 成人精品视频久久久久| www.日本在线观看| 成人美女在线视频| 久久久一本精品99久久精品| 黄色大片在线看| 国产精品久久福利| 99视频精品全部免费看| 成人影音在线| 91精品91久久久中77777| 中文字幕av不卡在线| 亚洲视频自拍| 亚洲成人国产精品| 一级黄色片大全| 天天操综合网| 午夜精品久久17c| 亚洲综合图片网| 精品一区二区在线视频| 国产精品美女久久久久aⅴ| 国产福利精品在线| 亚洲综合精品视频| 国产99精品视频| 欧美日韩大片一区二区三区| 阿v免费在线观看| 一区二区三区美女视频| 欧美 国产 综合| 国产精品久久久久久久久久齐齐 | 欧美国产一级| 国模精品视频一区二区| 亚洲欧美一二三区| 国产成人小视频| 欧美日韩一区综合| 污的网站在线观看| 色噜噜狠狠色综合欧洲selulu| 五月天视频在线观看| 国产成人精品亚洲线观看| 亚洲色图色老头| 久久免费视频99| 男女视频一区二区| 好看的日韩精品| 黄网页免费在线观看| 狠狠色噜噜狠狠狠狠97| 中文字幕色网站| 欧美猛男同性videos| 欧美国产日韩视频| 亚洲天堂2021av| 26uuu精品一区二区三区四区在线| 天天干天天操天天干天天操| 天堂中文在线播放| 日韩欧美国产不卡| 东京热无码av男人的天堂| 国产视频一区欧美| 51精品国产人成在线观看| 国产黄色片在线观看| 精品久久久久久中文字幕一区奶水| 欧美激情第一区| 色男人天堂综合再现| 热久久免费视频精品| 日韩中文字幕影院| 一区二区在线观看视频| 女人高潮一级片| 成人羞羞视频播放网站| 欧美在线观看网址综合| 人妻视频一区二区三区| 一区二区三区视频在线看| 男人的天堂最新网址| 欧美图片自拍偷拍| 天堂资源在线亚洲| 性视频1819p久久| 亚洲精品国产一区二| 亚洲天堂免费在线观看视频| 中文字幕国产免费| av一区二区高清| 国产成人+综合亚洲+天堂| 午夜小视频免费| 五月天久久比比资源色| 波多野结衣一二三区| 国内揄拍国内精品久久| av激情久久| 深夜国产在线播放| 日韩精品中文字幕一区二区三区| 久久国产精品国语对白| 激情成人综合网| a级黄色片网站| 国产精品一区免费在线| 欧美不卡视频一区发布| 不卡av中文字幕| 亚洲综合激情另类小说区| 人妻互换一二三区激情视频| 亚洲经典自拍| 六月婷婷久久| 中文另类视频| 精品国产欧美一区二区三区成人| 国产又粗又黄又爽| 中文字幕一区日韩精品欧美| 国产乱码一区二区三区四区| 午夜精品偷拍| 精品一区二区三区国产| 忘忧草在线影院两性视频| 亚洲一区二区福利| 伊人久久国产精品| 亚洲老妇xxxxxx| av在线播放网址| 日韩影院在线观看| 影音先锋亚洲视频| 成功精品影院| 日韩免费av在线| 国产精品久久麻豆| 精品成人一区二区| 日本久久综合网| 中文字幕一区二区三区在线播放 | 亚洲黄网在线观看| 中文字幕国产一区| 俄罗斯女人裸体性做爰| 国产一区二区三区成人欧美日韩在线观看 | 欧美日韩在线精品一区二区三区激情综合 | 在线观看男女av免费网址| 国产精品综合av一区二区国产馆| 午夜啪啪免费视频| 综合成人在线| 68精品国产免费久久久久久婷婷| 精品视频二区| 日韩亚洲欧美一区二区三区| 欧美多人猛交狂配| 另类综合日韩欧美亚洲| 国产一区二区四区| 精品久久美女| av成人午夜| 99精品在免费线偷拍| 欧美另类极品videosbestfree| 日色在线视频| 日韩美女一区二区三区四区| 中文字幕在线欧美| 亚洲精品国产无天堂网2021| jizz欧美性20| 国产乱国产乱300精品| 青青视频在线播放| 午夜精品国产| 亚洲一区二区精品在线| 天海翼亚洲一区二区三区| 成人高清视频观看www| 黄视频免费在线看| 欧美日韩第一视频| www 日韩| 日韩一级毛片| 国产成人精品电影久久久| av在线下载| 综合136福利视频在线| 四季av日韩精品一区| 91精品在线观看入口| 视频一区二区三区四区五区| 悠悠色在线精品| 国产无遮挡在线观看| 91丨porny丨蝌蚪视频| 精品偷拍各种wc美女嘘嘘| 黄色片网站在线播放| 91丨porny丨首页| 中国特级黄色大片| 久久99精品久久久久久国产越南| 成人黄色一区二区| 一本综合精品| 男女啪啪免费视频网站| 在线观看日韩| 大桥未久一区二区| 久久成人综合| 亚洲视频小说| 精品国产一区二区三区av片| 久久精品美女| 欧美日韩直播| 国产伦精品一区二区三区免费视频 | 精品人妻少妇AV无码专区| 欧美性xxxxxxxx| 波多野结衣理论片| 在线一区二区视频| 亚洲av无码不卡| 欧美日韩中文字幕日韩欧美| 国产成人愉拍精品久久| 亚洲国产成人91porn| 动漫精品一区一码二码三码四码| 亚洲精品第1页| 青青草手机在线观看| 亚洲乱码中文字幕| 日韩在线观看视频一区二区| 国产精品嫩模av在线| 日韩视频一区二区| 国产极品久久久| 欧美岛国在线观看| 欧美一级视频免费| 精品不卡在线视频| 四虎影院在线播放| 日韩久久午夜影院| 第一页在线观看| 日韩中文字幕国产| a级在线观看| 欧美肥婆姓交大片| 波多野结衣视频一区二区| 38少妇精品导航| 精品日本视频| 91久久久久久久久久久久久| 午夜视频在线观看精品中文| 黑人巨大精品欧美一区二区小视频| 免费成人av| 亚洲欧洲三级| 欧美视频久久| 国产精品97在线| 狠狠色伊人亚洲综合成人| 欧美人与性动交α欧美精品| 不卡一卡二卡三乱码免费网站| 最新中文字幕视频| 国产精品免费av| 免费网站看av| 色偷偷成人一区二区三区91| 一道本无吗一区| 亚洲精品一区二区三区四区高清| 网站黄在线观看| 中文字幕无线精品亚洲乱码一区| 含羞草www国产在线视频| 性欧美激情精品| 欧美成人福利| 国产原创精品| 久久在线视频免费观看| 日本高清+成人网在线观看| 黄视频网站免费看| 一区二区三区小说| 国产剧情在线视频| 欧美一区二区三区日韩视频| 日本黄色免费视频| 日韩在线观看视频免费| 99在线视频影院| 国产精品嫩草视频| 猫咪成人在线观看| 一区二区不卡在线| 99成人免费视频| 黄色aaaaaa| 久久精品视频免费观看| 欧美日韩国产一二三区| 午夜精品久久久久久久99樱桃| 中文字幕视频一区二区| 亚洲国产精品久久| 巨大荫蒂视频欧美大片| 欧美亚州一区二区三区| av在线成人| 日本在线观看一区| 伊人久久婷婷| 亚洲精品性视频| 久久精品日产第一区二区三区高清版 | 欧美美最猛性xxxxxx| 欧美性suv| 精品视频导航| 欧美视频久久| 亚洲精品在线网址| 国产欧美日韩在线观看| 91久久国产视频| 日韩欧美黄色影院| 蜜桃视频网站在线| 国产精品精品久久久| 色狼人综合干| 99热亚洲精品| 成人在线综合网| 538精品在线视频| 欧美人狂配大交3d怪物一区| 国产青青草在线| 人体精品一二三区| 日韩av黄色在线| 国产精品裸体瑜伽视频| 国产mv日韩mv欧美| 永久久久久久久| 69堂国产成人免费视频| 视频免费一区| 国产日韩精品综合网站| 精品久久久久久久| 一区二区xxx| 国产欧美va欧美不卡在线| 久久精品五月天| 亚洲午夜女主播在线直播| 中文不卡1区2区3区| 久久久久久欧美精品色一二三四| 亚洲激情影院| 亚洲精品乱码久久| 欧美日韩国产区| 偷拍25位美女撒尿视频在线观看| 97在线视频一区| 亚洲aaa级| 黄色av免费在线播放| 久久精品人人做人人综合 | 一级片一级片一级片| 欧美精品1区2区| 久久免费精彩视频| 午夜在线观看免费一区| 久久艹这里只有精品| 亚洲精品国产第一综合99久久| 国产成人精品a视频| 色中色综合影院手机版在线观看| 伊人久久影院| 一二三四视频社区在线| 91一区二区三区在线播放| 亚洲欧美自拍视频| 一区三区二区视频| 91精品亚洲一区在线观看| 欧美日韩dvd| 97精品久久久久中文字幕| 男人天堂视频网| 久久精品小视频| 超碰成人在线观看| 日韩一级在线免费观看| 欧美高清在线精品一区| 99久久夜色精品国产亚洲| 久久免费福利视频| 精品国产乱码| 亚洲视频在线不卡| 精品国产乱码久久久久久天美| 国产尤物视频在线| 亚洲最大福利视频网站| 中国女人久久久| 欧美一级特黄高清视频| 精品美女一区二区三区| 最新日韩精品| 中文字幕在线乱| www一区二区| 97人妻精品一区二区三区软件| 欧美精品九九久久| 欧美自拍偷拍| 无码人妻一区二区三区在线| 欧美在线你懂的| 欧美xxxx免费虐| 亚洲 国产 日韩 综合一区| 成人永久免费视频| 中文字幕永久免费视频| 亚洲2020天天堂在线观看| 日韩在线不卡| 无码人妻精品一区二区三应用大全|