摘要:實戰讀書筆記第一章從方法傳遞到接著上次的,繼續來了解一下,如果繼續簡化代碼。去掉并且生成的數字是萬,所消耗的時間循序流并行流至于為什么有時候并行流效率比循序流還低,這個以后的文章會解釋。
《Java8實戰》-讀書筆記第一章(02) 從方法傳遞到Lambda
接著上次的Predicate,繼續來了解一下,如果繼續簡化代碼。
把方法作為值來傳遞雖然很有用,但是要是有很多類似與isHeavyApple和isGreenApple這種可能只用一兩次的方法定義一堆確實有點煩人。為了解決這個問題,Java8它引入了一套新記法(匿名函數或Lambda),然你可以這樣寫:
ListisRedApples = filterApples(FilteringApples.apples, apple -> "red".equals(apple.getColor()));
或者是:
ListappleList = filterApples(FilteringApples.apples, apple -> apple.getWeight() < 120 && "red".equals(apple.getColor()));
甚至,你都可以不需要使用filterApples這個方法了,直接使用Stream中的filter方法就可以解決了:
ListisGreenApple = apples.stream().filter(apple -> "green".equals(apple.getColor())) .collect(Collectors.toList());
酷,看起來很不錯。所以,你甚至都不需要為只用一次的方法寫定義;這樣的代碼看起來更簡潔、更清晰,因為你用不著去找自己到底傳遞了什么代碼。
流在剛剛篩選蘋果的過程中,就有使用到Stream(流)其中的一個方法,這個Stream和InputStream、OutputStream是兩個完全不同的東西。Stream它是Java8中的一個核心新特,它是一套新的用來處理集合的API,有很多類似與filter這樣的方法而且使用起來非常的簡單和簡潔,可以簡化大部分代碼并且在并行的情況下利用多核CPU,能很有效的提升對集合處理的性能。
本章只是簡單的介紹了一下流的使用方式,至于流的詳細用法后面的章節會提到的。
現在,有一串字符串,需要進行篩選并且轉為大寫以進行排序,在Java8之前是我們是這么干的:
ListstringList = Arrays.asList("a1", "a2", "b1", "c1", "c2", "c4", "c3"); List cList = new ArrayList<>(); for (String s : stringList) { // 篩選出以c開頭的字符串 if (s.startsWith("c")) { // 將以c開頭的字符串轉為大寫,添加到集合 cList.add(s.toUpperCase()); } } // 排序 Collections.sort(cList); // 遍歷打印 for (String s : cList) { System.out.println(s); }
這樣的代碼看起來很頭疼,需要寫這么長一段的代碼,在Java8中可以使用Stream進行優化:
ListstringList = Arrays.asList("a1", "a2", "b1", "c1", "c2", "c4", "c3"); stringList.stream() // 篩選出以c開頭的字符串 .filter(s -> s.startsWith("c")) // 將剛剛以c開頭的字符串轉為大寫 .map(String::toUpperCase) // 排序 .sorted() // 循環遍歷 .forEach(System.out::println);
太棒了,只需要短短的一行代碼就可以完成!但是,使用Stream它也是有缺點的,它的性能不如foreach的效率高為了解決這個問題,Stream支持并。使用并行能極大的利用多核CPU的優勢,例如說:這些代碼原本只是用單核進行處理,現在有一臺8核的CPU電腦,那么它的處理速度就會是單核的八倍。
我們來進行比較一下,生成一個0-100的數字并寫入到文件中,循序流VS并行流誰的效率更高.
循序流:
long startTime = System.currentTimeMillis(); OutputStream out = new FileOutputStream(new File("D:/integer1.txt")); IntStream.rangeClosed(0, 100) .forEach(i -> { try { Thread.sleep(100L); out.write(i); } catch (IOException | InterruptedException e) { e.printStackTrace(); } }); long endTime = System.currentTimeMillis(); System.out.println("循序流:" + (endTime - startTime));
并行流:
long startTime = System.currentTimeMillis(); OutputStream out = new FileOutputStream(new File("D:/integer2.txt")); IntStream.rangeClosed(0, 100) .parallel().forEach(i -> { try { Thread.sleep(100L); out.write(i); } catch (IOException | InterruptedException e) { e.printStackTrace(); } }); long endTime = System.currentTimeMillis(); System.out.println("并行流:" + (endTime - startTime));
執行結果(I5-6200U的筆記本上執行結果):
循序流:10251 并行流:2620
效率明顯要比循序流快很多嘛!但是,并行流并不是萬能的,如果把sleep去掉后并且數字加到100萬,你會發現運行的時間比循序流還要長。
去掉sleep并且生成的數字是0-100萬,所消耗的時間:
循序流:2775 并行流:3346
至于為什么有時候并行流效率比循序流還低,這個以后的文章會解釋。
默認方法默認方法是Java8中的一個新特性,它的出現使得接口的升級變得平滑了,因為子類不是必須再去顯式的實現接口中的方法了。
例如:在Java8中,你可以直接調用List接口中的sort方法、它是用Java8 List接口中如下所示的默認方法實現的:
default void sort(Comparator super E> c) { Object[] a = this.toArray(); Arrays.sort(a, (Comparator) c); ListIteratori = this.listIterator(); for (Object e : a) { i.next(); i.set((E) e); } }
這意味著List的任何實體類都不需要顯式的實現sort,而在以前的Java版本中,除非提供了sort的實現,否則這些實體類都無法編譯通過。但是,默認方法也存在著一些問題,一個類可以實現多個接口,那么好幾個接口多有同樣的默認方法,那么這是否意味著Java中有了某種形式的多繼承?如果是多繼承,那么會不會出現像C++中菱形繼承的問題?這些問題以后的文章中都會有解釋和解決方案。
第一章總結:
了解了Java8中的一些核心新特性,例如:Lambda表達式、Stream、默認方法。
了解了Lambda表達式和Stream為代碼帶來的簡潔性。
并行流帶來的好處。
Java8中的默認方法帶來的好處。
代碼案例:
chap1
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/76641.html
摘要:依舊使用剛剛對蘋果排序的代碼。現在,要做的是篩選出所有的綠蘋果,也許你會這一個這樣的方法在之前,基本上都是這樣寫的,看起來也沒什么毛病。但是,現在又要篩選一下重量超過克的蘋果。 《Java8實戰》-讀書筆記第一章(01) 最近一直想寫點什么東西,卻不知該怎么寫,所以就寫寫關于看《Java8實戰》的筆記吧。 第一章內容較多,因此打算分幾篇文章來寫。 為什么要關心Java8 自1996年J...
摘要:上下文比如,接受它傳遞的方法的參數,或者接受它的值得局部變量中表達式需要類型稱為目標類型。但局部變量必須顯示的聲明,或實際上就算。換句話說,表達式只能捕獲指派給它們的局部變量一次。注捕獲實例變量可以被看作捕獲最終局部變量。 由于第三章的內容比較多,而且為了讓大家更好的了解Lambda表達式的使用,也寫了一些相關的實例,可以在Github或者碼云上拉取讀書筆記的代碼進行參考。 類型檢查、...
摘要:第三個問題查找所有來自于劍橋的交易員,并按姓名排序。第六個問題打印生活在劍橋的交易員的所有交易額。第八個問題找到交易額最小的交易。 付諸實戰 在本節中,我們會將迄今學到的關于流的知識付諸實踐。我們來看一個不同的領域:執行交易的交易員。你的經理讓你為八個查詢找到答案。 找出2011年發生的所有交易,并按交易額排序(從低到高)。 交易員都在哪些不同的城市工作過? 查找所有來自于劍橋的交易...
摘要:之前,使用匿名類給蘋果排序的代碼是的,這段代碼看上去并不是那么的清晰明了,使用表達式改進后或者是不得不承認,代碼看起來跟清晰了。這是由泛型接口內部實現方式造成的。 # Lambda表達式在《Java8實戰》中第三章主要講的是Lambda表達式,在上一章節的筆記中我們利用了行為參數化來因對不斷變化的需求,最后我們也使用到了Lambda,通過表達式為我們簡化了很多代碼從而極大地提高了我們的...
摘要:但是到了第二天,他突然告訴你其實我還想找出所有重量超過克的蘋果。現在,農民要求需要篩選紅蘋果。那么,我們就可以根據條件創建一個類并且實現通過謂詞篩選紅蘋果并且是重蘋果酷,現在方法的行為已經取決于通過對象來實現了。 通過行為參數化傳遞代碼 行為參數化 在《Java8實戰》第二章主要介紹的是通過行為參數化傳遞代碼,那么就來了解一下什么是行為參數化吧。 在軟件工程中,一個從所周知的問題就是,...
閱讀 3775·2021-09-02 09:53
閱讀 2753·2021-07-30 14:57
閱讀 3495·2019-08-30 13:09
閱讀 1200·2019-08-29 13:25
閱讀 813·2019-08-29 12:28
閱讀 1459·2019-08-29 12:26
閱讀 1133·2019-08-28 17:58
閱讀 3308·2019-08-26 13:28