最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java8之lambda最佳實踐_動力節(jié)點(diǎn)Java學(xué)院整理

 更新時間:2017年06月01日 09:41:13   投稿:mrr  
在8 里面Lambda是最火的主題,不僅僅是因為語法的改變,更重要的是帶來了函數(shù)式編程的思想,我覺得優(yōu)秀的程序員,有必要學(xué)習(xí)一下函數(shù)式編程的思想以開闊思路

在8 里面Lambda是最火的主題,不僅僅是因為語法的改變,更重要的是帶來了函數(shù)式編程的思想,我覺得優(yōu)秀的程序員,有必要學(xué)習(xí)一下函數(shù)式編程的思想以開闊思路。所以這篇文章聊聊Lambda的應(yīng)用場景,性能,也會提及下不好的一面。

Java為何需要Lambda

1996年1月,Java 1.0發(fā)布了,此后計算機(jī)編程領(lǐng)域發(fā)生了翻天覆地的變化。商業(yè)發(fā)展需要更復(fù)雜的應(yīng)用,大多數(shù)程序都跑在更強(qiáng)大的裝備多核CPU的機(jī)器上。帶有高效運(yùn)行期編譯器的Java虛擬機(jī)(JVM)的出現(xiàn),使得程序員將精力更多放在編寫干凈、易于維護(hù)的代碼上,而不是思考如何將每一個CPU時鐘、每一字節(jié)內(nèi)存物盡其用。

多核CPU的出現(xiàn)成了“房間里的大象”,無法忽視卻沒人愿意正視。算法中引入鎖不但容易出錯,而且消耗時間。人們開發(fā)了java.util.concurrent包和很多第三方類庫,試圖將并發(fā)抽象化,用以幫助程序員寫出在多核CPU上運(yùn)行良好的程序。不幸的是,到目前為止,我們走得還不夠遠(yuǎn)。

那些類庫的開發(fā)者使用Java時,發(fā)現(xiàn)抽象的級別還不夠。處理大數(shù)據(jù)就是個很好的例子,面對大數(shù)據(jù),Java還欠缺高效的并行操作。Java 8允許開發(fā)者編寫復(fù)雜的集合處理算法,只需要簡單修改一個方法,就能讓代碼在多核CPU上高效運(yùn)行。為了編寫并行處理這些大數(shù)據(jù)的類庫,需要在語言層面上修改現(xiàn)有的Java:增加lambda表達(dá)式。

當(dāng)然,這樣做是有代價的,程序員必須學(xué)習(xí)如何編寫和閱讀包含lambda表達(dá)式的代碼,但是,這不是一樁賠本的買賣。與手寫一大段復(fù)雜的、線程安全的代碼相比,學(xué)習(xí)一點(diǎn)新語法和一些新習(xí)慣容易很多。開發(fā)企業(yè)級應(yīng)用時,好的類庫和框架極大地降低了開發(fā)時間和成本,也掃清了開發(fā)易用且高效的類庫的障礙。

Lambda的應(yīng)用場景

下面我將重點(diǎn)放在函數(shù)式編程的實用性上,包括那些可以被大多數(shù)程序員理解和使用的技術(shù),我們關(guān)心的如何寫出好代碼,而不是符合函數(shù)編程風(fēng)格的代碼。

1.1.1 1.使用() -> {} 替代匿名類

現(xiàn)在Runnable線程,Swing,JavaFX的事件監(jiān)聽器代碼等,在java 8中你可以使用Lambda表達(dá)式替代丑陋的匿名類。

//Before Java 8:
new Thread(new Runnable() {
 @Override
 public void run() {
  System.out.println("Before Java8 ");
 }
}).start();
//Java 8 way:
new Thread(() -> System.out.println("In Java8!"));
// Before Java 8:
JButton show = new JButton("Show");
show.addActionListener(new ActionListener() {
  @Override
  public void actionPerformed(ActionEvent e) {
   System.out.println("without lambda expression is boring");
  }
  });
// Java 8 way:
show.addActionListener((e) -> {
 System.out.println("Action !! Lambda expressions Rocks");
});

使用內(nèi)循環(huán)替代外循環(huán)

外循環(huán):描述怎么干,代碼里嵌套2個以上的for循環(huán)的都比較難讀懂;只能順序處理List中的元素;

內(nèi)循環(huán):描述要干什么,而不是怎么干;不一定需要順序處理List中的元素

//Prior Java 8 :
List features = Arrays.asList("Lambdas", "Default Method", 
"Stream API", "Date and Time API");
for (String feature : features) {
 System.out.println(feature);
}
//In Java 8:
List features = Arrays.asList("Lambdas", "Default Method", "Stream API",
 "Date and Time API");
features.forEach(n -> System.out.println(n));
// Even better use Method reference feature of Java 8
// method reference is denoted by :: (double colon) operator
// looks similar to score resolution operator of C++
features.forEach(System.out::println);

Output:
Lambdas
Default Method
Stream API
Date and Time API

支持函數(shù)編程

為了支持函數(shù)編程,Java 8加入了一個新的包java.util.function,其中有一個接口java.util.function.Predicate是支持Lambda函數(shù)編程:

public static void main(args[]){
 List languages = Arrays.asList("Java", "Scala", "C++", "Haskell", "Lisp");
 System.out.println("Languages which starts with J :");
 filter(languages, (str)->str.startsWith("J"));
 System.out.println("Languages which ends with a ");
 filter(languages, (str)->str.endsWith("a"));
 System.out.println("Print all languages :");
 filter(languages, (str)->true);
 System.out.println("Print no language : ");
 filter(languages, (str)->false);
 System.out.println("Print language whose length greater than 4:");
 filter(languages, (str)->str.length() > 4);
}
 public static void filter(List names, Predicate condition) {
 names.stream().filter((name) -> (condition.test(name)))
  .forEach((name) -> {System.out.println(name + " ");
 });
 }
Output:
Languages which starts with J :
Java
Languages which ends with a
Java
Scala
Print all languages :
Java
Scala
C++
Haskell
Lisp
Print no language :
Print language whose length greater than 4:
Scala
Haskell

處理數(shù)據(jù)?用管道的方式更加簡潔

Java 8里面新增的Stream API ,讓集合中的數(shù)據(jù)處理起來更加方便,性能更高,可讀性更好

假設(shè)一個業(yè)務(wù)場景:對于20元以上的商品,進(jìn)行9折處理,最后得到這些商品的折后價格。

final BigDecimal totalOfDiscountedPrices = prices.stream()
.filter(price -> price.compareTo(BigDecimal.valueOf(20)) > 0)
.map(price -> price.multiply(BigDecimal.valueOf(0.9)))
.reduce(BigDecimal.ZERO,BigDecimal::add);
System.out.println("Total of discounted prices: " + totalOfDiscountedPrices);

想象一下:如果用面向?qū)ο筇幚磉@些數(shù)據(jù),需要多少行?多少次循環(huán)?需要聲明多少個中間變量?

Lambda的陰暗面

前面都是講Lambda如何改變Java程序員的思維習(xí)慣,但Lambda確實也帶來了困惑

JVM可以執(zhí)行任何語言編寫的代碼,只要它們能編譯成字節(jié)碼,字節(jié)碼自身是充分OO的,被設(shè)計成接近于Java語言,這意味著Java被編譯成的字節(jié)碼非常容易被重新組裝。

但是如果不是Java語言,差距將越來越大,Scala源碼和被編譯成的字節(jié)碼之間巨大差距是一個證明,編譯器加入了大量合成類 方法和變量,以便讓JVM按照語言自身特定語法和流程控制執(zhí)行。

我們首先看看Java 6/7中的一個傳統(tǒng)方法案例:

// simple check against empty strings
public static int check(String s) {
 if (s.equals("")) {
  throw new IllegalArgumentException();
 }
 return s.length();
}
//map names to lengths
List lengths = new ArrayList();
for (String name : Arrays.asList(args)) {
 lengths.add(check(name));
}

如果一個空的字符串傳入,這段代碼將拋出錯誤,堆棧跟蹤如下:

at LmbdaMain.check(LmbdaMain.java:19)
at LmbdaMain.main(LmbdaMain.java:34)

再看看Lambda的例子

Stream lengths = names.stream().map(name -> check(name));
 at LmbdaMain.check(LmbdaMain.java:19)
at LmbdaMain.lambda$0(LmbdaMain.java:37)
at LmbdaMain$$Lambda$1/821270929.apply(Unknown Source)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:512)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:502)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.LongPipeline.reduce(LongPipeline.java:438)
at java.util.stream.LongPipeline.sum(LongPipeline.java:396)
at java.util.stream.ReferencePipeline.count(ReferencePipeline.java:526)
at LmbdaMain.main(LmbdaMain.java:39)

 這非常類似Scala,出錯棧信息太長,我們?yōu)榇a的精簡付出力代價,更精確的代碼意味著更復(fù)雜的調(diào)試。
但這并不影響我們喜歡Lambda!

總結(jié)

在Java世界里面,面向?qū)ο筮€是主流思想,對于習(xí)慣了面向?qū)ο缶幊痰拈_發(fā)者來說,抽象的概念并不陌生。面向?qū)ο缶幊淌菍?shù)據(jù)進(jìn)行抽象,而函數(shù)式編程是對行為進(jìn)行抽象?,F(xiàn)實世界中,數(shù)據(jù)和行為并存,程序也是如此,因此這兩種編程方式我們都得學(xué)。

這種新的抽象方式還有其他好處。很多人不總是在編寫性能優(yōu)先的代碼,對于這些人來說,函數(shù)式編程帶來的好處尤為明顯。程序員能編寫出更容易閱讀的代碼——這種代碼更多地表達(dá)了業(yè)務(wù)邏輯,而不是從機(jī)制上如何實現(xiàn)。易讀的代碼也易于維護(hù)、更可靠、更不容易出錯。

在寫回調(diào)函數(shù)和事件處理器時,程序員不必再糾纏于匿名內(nèi)部類的冗繁和可讀性,函數(shù)式編程讓事件處理系統(tǒng)變得更加簡單。能將函數(shù)方便地傳遞也讓編寫惰性代碼變得容易,只有在真正需要的時候,才初始化變量的值。
總而言之,Java更趨于完美了。

相關(guān)文章

  • Java大小寫轉(zhuǎn)換及一些常見的注意事項詳解

    Java大小寫轉(zhuǎn)換及一些常見的注意事項詳解

    這篇文章主要介紹了Java大小寫轉(zhuǎn)換及一些常見的注意事項的相關(guān)資料,Java提供了多種方法進(jìn)行大小寫轉(zhuǎn)換,包括String類的toLowerCase和toUpperCase方法,以及Character類的toLowerCase和toUpperCase方法,需要的朋友可以參考下
    2025-02-02
  • Java Socket編程實例(二)- UDP基本使用

    Java Socket編程實例(二)- UDP基本使用

    這篇文章主要講解Java Socket編程中UDP的基本使用,希望能給大家做一個參考。
    2016-06-06
  • Bloc事件流是一個阻塞隊列結(jié)論解析

    Bloc事件流是一個阻塞隊列結(jié)論解析

    這篇文章主要為大家介紹了Bloc事件流是一個阻塞隊列結(jié)論解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • Spring2.5.6開發(fā)環(huán)境搭建圖文教程

    Spring2.5.6開發(fā)環(huán)境搭建圖文教程

    這篇文章主要為大家詳細(xì)介紹了Spring2.5.6開發(fā)環(huán)境搭建圖文教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • java如何根據(jù)日期生成單號

    java如何根據(jù)日期生成單號

    這篇文章主要介紹了java如何根據(jù)日期生成單號問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-09-09
  • javaWeb中使用Redis緩存實例解析

    javaWeb中使用Redis緩存實例解析

    這篇文章主要介紹了javaWeb中使用Redis緩存實例解析,具有一定借鑒價值,需要的朋友可以參考下
    2018-01-01
  • 關(guān)于spring中aop的注解實現(xiàn)方法實例詳解

    關(guān)于spring中aop的注解實現(xiàn)方法實例詳解

    這篇文章主要給大家介紹了關(guān)于spring中aop的注解實現(xiàn)方法的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面跟著小編來一起看看吧。
    2017-08-08
  • Java使用substring()截取(提取)子字符串

    Java使用substring()截取(提取)子字符串

    這篇文章主要介紹了Java使用substring()截取(提取)子字符串,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • IDEA的Swing可視化插件JFormDesigner詳解

    IDEA的Swing可視化插件JFormDesigner詳解

    JFormDesigner是一個專業(yè)的軟件應(yīng)用程序,專門用于幫助您開發(fā)Java?Swing用戶界面,而無需具備編程技能。它可作為獨(dú)立實用程序使用,也可以將其用作各種IDE的插件,本文給大家介紹idea?Swing可視化插件,感興趣的朋友一起看看吧
    2022-06-06
  • 基于Java編寫一個PDF與Word文件轉(zhuǎn)換工具

    基于Java編寫一個PDF與Word文件轉(zhuǎn)換工具

    前段時間一直使用到word文檔轉(zhuǎn)pdf或者pdf轉(zhuǎn)word,尋思著用Java應(yīng)該是可以實現(xiàn)的,于是花了點(diǎn)時間寫了個文件轉(zhuǎn)換工具,感興趣的可以了解一下
    2023-01-01

最新評論

安康市| 建昌县| 蕉岭县| 武清区| 通州市| 驻马店市| 永胜县| 濉溪县| 盖州市| 合川市| 洪湖市| 来安县| 兴文县| 新昌县| 新沂市| 棋牌| 康乐县| 南华县| 祁阳县| 乐清市| 漠河县| 宜宾县| 吉木乃县| 江达县| 金乡县| 勃利县| 新乡市| 五台县| 新田县| 巴塘县| 抚宁县| 博爱县| 竹溪县| 新田县| 光山县| 辰溪县| 西充县| 旺苍县| 屯门区| 阿勒泰市| 彭阳县|