亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > Java > 正文

如何更快樂的使用Java 8中的Lambda特性

2024-07-14 08:42:44
字體:
來源:轉載
供稿:網友

前言

Java 8 的 Lambda 特性較之于先前的泛型加入更能鼓舞人心的,我對 Lambda 的理解是它得以讓 Java 以函數式思維的方式來寫代碼。而寫出的代碼是否是函數式,并不單純在包含了多少 Lambda 表達式,而在思維,要神似。

實際中看過一些代碼,為了 Lambda 表達式而 Lambda(函數式),有一種少年不識愁滋味,為賦新詞強說愁的味道。從而致使原本一個簡單的方調用硬生生的要顯式的用類如 apply(), accept(obj) 等形式。不僅造成代碼可讀性差,且可測試性也變壞了。

為什么說的是快樂的使用 Java 8 的 Lambda 呢?我竊以為第一個念頭聲明 Lambda 表達式為實例/類變量(像本文第一段代碼那樣),而不是方法的,一定會覺得如此使用方式很快樂的。所謂獨樂樂,不如眾樂樂;獨樂樂,眾不樂定然是更大的快樂; 更極致一些,不管什么時候必須是:我快樂,所以你也快樂。

一方面也在于 Java 還沒有進化到 JavaScript 或  Scala 那樣的水平,JavaScript 的函數類型變量,不一定要用 apply 或 call, 直接括號就能實現方法調用。Scala 的函數類型用括號調用也會自動匹配到 apply 或 update 等方法上去。

看下面的樣本代碼

public class Account {  public BiFunction<String, String, String> fullName = (firstName, lastName) -> {  //some logic, i.e. logics of fullName in different countries   return firstName + " " + lastName; };  public String getName() {  String firstName = "Speaker";  String lastName = "Wolf";  return fullName.apply(firstName, lastName); }}

上面的 fullName Lambda 表達式看起來就有點別扭,完全可以寫成一個普通方法

 public String makeFullName(String firstName, String lastName) {  //return something with logics }

那么調用起來只需要簡單的

makeFullName(firstName, lastName)

那么此例中把簡單方法寫成一個 Lambda 表達式來調用有什么不友好之處呢?

  • 不利于理解,Lambda 表達式的類型充斥著 Consumer, Function, BiFunction 等太寬泛的聲明
  • 參數類型與形參分離在表達式等號兩邊,不利于一一對應(右方重復一遍參數類型更不可取),真正的返回值也不明了
  • 調用時更得多余的 get(), accept(obj), apply(obj1, obj2) 那樣的方法
  • 既然有邏輯,就應該有測試,Lambda 表達式雖是一個變量也不例如,測試時也不得用 apply 那樣的調用
  • Lambda 表達式為變量的形式,可能會隨每一個對象實例有一單獨的拷貝。當然聲明為靜態可以避免。
  • 重構時更需大動干戈,比如前面的例子還要考慮 middleName 的情況,表達式要更動為
public TriFunction<String, String, String, String> fullName = (firstName, middleName, lastName) -> { //.......}

JDK 中還沒有 TriFunction, 還得自己創造,不同數量的參數都得更新 Lambda 表達式的類型。如果是一個普通方法重構起來就方便多了,跟多一個人多一副碗筷一樣。

 解釋上面第 #5 條,對于方法,實現代碼在 JVM 中只有一份,而 Lambda 實例變量如果不捕獲外部變量的話,與方法是一樣的,例如前面的 Account 為例

Account account1 = new Account();Account account2 = new Account();System.out.println(account1.fullName == account2.fullName); //true

但是 Lambda 表達式需捕獲外部變量時,例如

private String suffix = "Sir";public BiFunction<String, String, String> fullName = (firstName, lastName) -> { return firstName + " " + lastName + " " + suffix;}; .......Account account1 = new Account();Account account2 = new Account();account1.fullName == account2.fullName; //就是 false 了, 而如果 suffix 是一個靜態的變量時這個等式又是 true 了

那么新建的兩個 Account 對象的 fullName 屬性就不是同一個了。因為 Lambda 需要捕獲外部一個不確定的值,所以它也隨宿主實例也變。

難道不應該用 Lambda 表達式變量,那倒不是,如果一個方法接受的是一個函數,如

public String getName(BiFunction<String, String, String> builder) { return builder.apply(firstName, lastName);}

那么是可以聲明一個 Lambda 表達式變量,來傳入。不過這種情況下用方法引用還是更方便些,方法的測試總是比 Lambda 表達式的測試容易。

String name = getName(this::makeFullName);

個人習慣,一般需要 Lambda 表達式變量時基本是聲明為局部變量,或是調用接受函數參數的方法時以內聯的方法書寫,像

String name = getName((firstName, lastName) -> { //logics return ......});

對于使用方法引用方式的重構也不難,getName() 的參數類型變為 TriFunction, makeFullName() 方法再加一個參數就行, 調用形式仍然不變,還是

String name = getName(this::makeFullName);

如果引用的方法是別人寫的也不用慌,無須總去創建一樣的方法簽名來強型上方法引用,也可以和改 Lambda 實現代碼一樣的方式比改動,如下

String name = getName((firstName, lastName) ->  makeFullName(firstName, lastName) + " " + suffix)

本人希望的是,對函數的 apply(), accept(obj) 這樣的顯式調用應該是框架設計實現的職責,對框架使用者應該透明,或者說是隱藏背后的細節,只管傳入需要的函數類型或方法引用。如果函數實現需要共享的話,寫成方法更優于一個 Lambda 表達式,方法容易單獨測試。特別是用 Mockito 捕獲到了一個傳入某個方法的 Lambda  表達式實例時,不那么好驗證它的內部實現。

小結一下:

  • 函數式思維最關鍵應該是 Data In, Data Out, 編程語言 Lambda 特性可以促使我們達成這一目的; 但不是代碼中有了  Lambda 表達就是函數式風格。
  • 其次代碼的首先是人閱讀,其次才是機器,所以它應該表達直截,明了,很強的可讀性與可測試性。
  • 具體講如何快樂使用 Java 8 的 Lambda 呢,僅代表本人想法,可以用內聯式,或方法引用,或局部的 Lambda 表達式變量,最后才是實例/類的 Lambda 表達式變量。

補充一個例子,在方法體中重復聲明完全相同的不捕獲任何外部變量的 Lambda 表達式都是新的實例

 Consumer<String> f1 = a -> System.out.println(a); Consumer<String> f2 = a -> System.out.println(a); System.out.println(f1 == f2); //false

以上測試在 Java 8 平臺上進行的。

lambda表達式優劣

lambda表達式有優點也有缺點,優點在于大大簡化代碼行數,使代碼在一定程度上變的簡潔干凈,但是同樣的,這可能也會是一個缺點,由于省略了太多東西,代碼可讀性有可能在一定程度上會降低,這個完全取決于你使用lambda表達式的位置所設計的API是否被你的代碼的其他閱讀者所熟悉。另外的優點,也是lambda表達式比較顯眼的優點就是對外部定義的局部變量的使用更加靈活,想象一種極端情況,你的代碼中有地方需要接口回調套接口回調,有可能套了好幾層,雖然這種情況出現的概率比較低,但是一旦出現這種代碼,lambda表達式的這個優點就到了大顯身手的時機。雖然我說了,lambda表達式能用的地方非常有限,但是不得不否認,接口中只有一個抽象方法這種情況在接口回調中發生的概率絕對比接口中有多個抽象方法的概率高的多,所以,雖然使用情況很單一,但是能用到的次數卻足夠的多,如果你決定用lambda表達式替換你項目中接口回調的傳統寫法,你會發現,這樣的情況非常多。

總而言之,接口回調和lambda表達式這兩種寫法各有優劣,java 8在出現lambda表達式以后不代表原先的寫法不能再用了,所以如何選擇適合項目的寫法,全看各位開發者如何自己選擇,現在多了一種寫法可選,總歸是一件好事。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VeVb武林網的支持。


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
大胆人体色综合| 97精品国产97久久久久久春色| 久久艹在线视频| 538国产精品一区二区免费视频| 97在线看免费观看视频在线观看| 久久久99免费视频| 日韩中文字幕免费| 欧美精品久久久久a| 91精品国产高清久久久久久91| 亚洲丁香久久久| 日本久久亚洲电影| 91视频国产高清| 这里只有精品视频| 欧美日韩亚洲一区二区三区| 日本精品久久中文字幕佐佐木| 亚洲一区二区在线播放| 欧美成人在线影院| 日韩欧美亚洲综合| 国产+成+人+亚洲欧洲| 伊人久久男人天堂| 国内外成人免费激情在线视频| 911国产网站尤物在线观看| 国产精品福利片| 国产婷婷97碰碰久久人人蜜臀| 国产在线精品成人一区二区三区| 精品成人乱色一区二区| 欧美国产视频一区二区| 欧美片一区二区三区| 欧美性猛交xxxx| 国产精品久久久久久久久久久不卡| 成人av色在线观看| 国产精品吹潮在线观看| 欧美一级大胆视频| 国产精品偷伦视频免费观看国产| 亚洲一级片在线看| 国产欧美欧洲在线观看| 亚洲国产福利在线| 国产日韩一区在线| 国产视频综合在线| 日韩电影中文字幕在线| 91精品国产一区| 亚洲永久在线观看| 97香蕉久久夜色精品国产| 日韩电影免费观看中文字幕| 欧美精品久久久久久久免费观看| 91精品国产成人| 精品久久久一区| 亚洲毛片在线观看.| 久久手机精品视频| 亚洲国产精品999| 国产一区二区三区在线| 亚洲性夜色噜噜噜7777| 久久久精品亚洲| 国产精品一区二区三区免费视频| 欧美大尺度激情区在线播放| 亚洲成人亚洲激情| 视频在线观看99| 成人精品一区二区三区| 日韩国产欧美区| 日韩精品亚洲精品| 国产在线观看精品一区二区三区| 国产999精品视频| 国产精品美女免费| 在线观看日韩www视频免费| 国产精品入口尤物| www日韩欧美| 欧美夫妻性生活xx| 日韩电影中文字幕| 久久精品国产成人精品| 久久成人精品电影| 久久69精品久久久久久久电影好| 另类天堂视频在线观看| 久久久久久亚洲精品中文字幕| 日韩在线免费高清视频| 亚洲成av人乱码色午夜| 亚洲女性裸体视频| 日韩在线观看成人| 欧美成人精品不卡视频在线观看| 久久影院资源站| 57pao国产成人免费| 国产精品久久久久99| 亚州国产精品久久久| 亚洲成色999久久网站| 亚洲精品欧美极品| 日本a级片电影一区二区| 亚洲一区二区三区四区视频| 欧美国产日产韩国视频| 亚洲美女久久久| 精品国产一区久久久| 国产精品免费久久久久影院| 国产精品一区二区av影院萌芽| 久久6精品影院| 久久国产精品久久久| 麻豆国产va免费精品高清在线| 福利精品视频在线| 国产精品扒开腿做爽爽爽男男| 北条麻妃久久精品| 高清日韩电视剧大全免费播放在线观看| 亚洲精品视频久久| 欧美一级淫片播放口| 欧美午夜女人视频在线| 国内精品久久久久久中文字幕| 精品一区二区三区四区在线| 欧美日韩美女视频| www.日韩欧美| 在线播放亚洲激情| 不卡av电影在线观看| 97激碰免费视频| 中文亚洲视频在线| 日韩av手机在线看| 中文一区二区视频| 国产精品永久免费视频| 日韩成人av一区| 一区二区三区黄色| 日本午夜在线亚洲.国产| 91高清视频在线免费观看| 一区二区三区四区在线观看视频| 日本国产高清不卡| 欧美成人免费观看| 欧美亚洲国产精品| 九九久久国产精品| 奇米影视亚洲狠狠色| 欧美在线视频一区| 国产盗摄xxxx视频xxx69| 久久成人亚洲精品| 高清欧美电影在线| 97视频网站入口| 97久久国产精品| 亚洲第一免费网站| 中文精品99久久国产香蕉| 性色av一区二区三区红粉影视| 亚洲午夜精品久久久久久久久久久久| 一本一道久久a久久精品逆3p| 久久免费高清视频| 亚洲欧美在线第一页| 亚洲国产另类 国产精品国产免费| 中文字幕亚洲一区| 日韩精品中文字| 久久香蕉国产线看观看av| 国产精品视频1区| 亚洲综合中文字幕68页| 国模吧一区二区三区| 色综合久久久久久中文网| 日韩中文字幕在线看| 亚洲日韩欧美视频一区| 国产精品jvid在线观看蜜臀| 九九精品在线视频| 欧美性生活大片免费观看网址| xxx一区二区| 日韩美女写真福利在线观看| 国内精品久久久久影院优| 国产在线观看精品| 欧洲亚洲妇女av| 久久av中文字幕| 亚洲人成电影网站色www| 亚洲韩国欧洲国产日产av| 国产99视频精品免视看7| 96国产粉嫩美女| 国产精品中文字幕在线| 精品成人国产在线观看男人呻吟| 欧美疯狂性受xxxxx另类| 亚洲第一区第二区| 亚洲精品久久久久久久久久久| 热久久99这里有精品|