摘要:自從出來過后,引入了流,函數式編程,就更不是在向著面向對象發展了。下面我就來探索一下,到底解決了一些什么問題。一個簡單的原則是要處理的問題規模很龐大,或處理單個問題特別耗時就可以考慮多線程了。
在學習面向對象時,許多人都會用Java來舉例子,但是其實Java并非純正的面向對象語言,最明顯的就是:int,double等基本類型不是對象。
自從java8出來過后,引入了流,函數式編程,就更不是在向著面向對象發展了。有人可能會感到詫異,為啥越來越偏離我們遵循了這么久的面向對象設計模式?
其實很簡單,我們對工具的改造的最終目的都是為了解決問題,以前有面向過程解決不了的問題,那么面向對象出來解決了;現在面向對象有許多問題,那么就可以用函數式編程來解決,所以這些變化是很自然的,Java要在不同時代的保持自己的活力,就必須與時俱進,所以Java8的出現就是自然而然的。
下面我就來探索一下,Java8到底解決了一些什么問題。
消除冗余類代碼假設有個類:
class People{ private String name; private int age; public People(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
現在有個list
Listworkers = new LinkedList<>(); workers.add( new People("aa",23)); workers.add( new People("abc",21)); workers.add( new People("cdf",18));
如果要對這個list按照People的年齡排序,并打印出來,那么在Java8之前會這樣寫:
workers.sort(new Comparator() { @Override public int compare(People o1, People o2) { return o1.getAge()>o2.getAge()?1:-1; } }); for (People p:workers ) { System.out.println(p.getName()+":"+p.getAge()); }
Java8引入了函數式編程的lambda表達式,就可以這樣寫了:
workers.sort((o1, o2) -> o1.getAge()>o2.getAge()?1:-1); for (People p:workers ) { System.out.println(p.getName()+":"+p.getAge()); }
進一步,使用方法引用就可以這樣寫:
workers.sort(Comparator.comparing(People::getAge)); for (People p:workers ) { System.out.println(p.getName()+":"+p.getAge()); }
這樣就更簡潔了,而且意圖也和清晰,可以不寫注釋就能讓別人明白,是按照年齡排序。
函數式的lambda表達式通過將函數提升為“一等公民”,使得直接傳遞函數成為可能,而不必再為了傳遞實現某個功能的函數而強行傳遞一個冗余的外包類。
內部迭代替代外部迭代stream允許你以聲明性方式處理數據集合,類似于SQL語句。我們直接看例子吧,上面那一段代碼已經很簡潔了,但是使用了流還可以更簡潔
workers.sort(Comparator.comparing(People::getAge)); workers.stream().map(p-> p.getName()+":"+p.getAge()).forEach(System.out::println);
這一段代碼根本就沒有循環了,Stream API 替你搞定了循環,這就是內部迭代 替代 外部迭代 ,
亦即API的設計者 替 使用者完成了迭代,代碼相當簡潔。
而且由于是內部迭代,所以Stream庫可以選擇最適合本機硬件的實現,達到性能優化的目的,如果是外部迭代,就需要調用者自己來優化了(你得承認許多API調用者沒有這種優化能力)。
如果我們有大量數據要處理,通常會使用多線程,在Java8之前,使用多線程是一件比較麻煩的事:
我們得自己合理的劃分數據
手動為每一部分數據多帶帶分配一個線程,還有可能會產生競態條件需要進行同步
完成每個線程的結果的合并,得到最終結果。
這個過程是比較麻煩的,易錯的。使用流能夠安全簡潔的使用多核,甚至于你都不需要關心多線程的具體實現。
傳統的循環:
ListintList = new LinkedList(); for (int i=0;i<20_000_000;i++){ intList.add(i+""); } long count = 0; long start = System.nanoTime(); for (String in:intList ) { if (Integer.parseInt(in)>1_123_345) count++; } long duration = (System.nanoTime() - start) / 1_000_000; System.out.println(duration);
結果:781,747,770
Java8的并行流:
ListintList = new LinkedList(); for (int i=0;i<20_000_000;i++){ intList.add(i+""); } long count = 0; long start = System.nanoTime(); count = intList.parallelStream().filter(p->Integer.parseInt(p)>1_123_345).count(); long duration = (System.nanoTime() - start) / 1_000_000; System.out.println(duration);
結果:665,683,662
可見我們并不需要顯式的進行多線程編程就能取得比單線程更好的結果,也就是Stream庫幫我們實現了多線程,更安全(不得不承認許多人寫的多線程代碼都是有問題的),更簡潔(我們不用寫多線程代碼了)。
稍微需要注意的是,多線程本身會帶來一定開銷,所以如果問題規模不夠大的話(具體數值取決于你的硬件),單線程反而優于多線程,所以使用之前要先考慮和測試,多線程到底能否帶來好處。一個簡單的原則是:要處理的問題規模很龐大,或處理單個問題特別耗時就可以考慮多線程了。
總之,Java8還有好多新特性,會幫我們解決許多以前無法解決的問題,所以我們要與時俱進,好好學習啊(~_~)。
歡迎反問我的主頁,Mageek(http://mageek.cn)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/70106.html
摘要:依舊使用剛剛對蘋果排序的代碼。現在,要做的是篩選出所有的綠蘋果,也許你會這一個這樣的方法在之前,基本上都是這樣寫的,看起來也沒什么毛病。但是,現在又要篩選一下重量超過克的蘋果。 《Java8實戰》-讀書筆記第一章(01) 最近一直想寫點什么東西,卻不知該怎么寫,所以就寫寫關于看《Java8實戰》的筆記吧。 第一章內容較多,因此打算分幾篇文章來寫。 為什么要關心Java8 自1996年J...
摘要:實戰讀書筆記第一章從方法傳遞到接著上次的,繼續來了解一下,如果繼續簡化代碼。去掉并且生成的數字是萬,所消耗的時間循序流并行流至于為什么有時候并行流效率比循序流還低,這個以后的文章會解釋。 《Java8實戰》-讀書筆記第一章(02) 從方法傳遞到Lambda 接著上次的Predicate,繼續來了解一下,如果繼續簡化代碼。 把方法作為值來傳遞雖然很有用,但是要是有很多類似與isHeavy...
摘要:注意當多個父接口中存在相同的默認方法時,子類中以就近原則繼承。定義靜態默認方法這是版簡易計算器接口默認方法使用定義接口并提供默認打印方法定義接口默認方法支持方法形參這是數值運算基本接口。。。 總概 JAVA8 已經發布很久,而且毫無疑問,java8是自java5(2004年發布)之后的最重要的版本。其中包括語言、編譯器、庫、工具和JVM等諸多方面的新特性。 Java8 新特性列表如下:...
摘要:使用解決的數據流問題原文譯者飛龍協議在年三月發布,距離現在年三月五號快有一年了。除了,最實用的特性是新的數據流。是吧,注是瀏覽器上的數據流的接口,并解決了上述問題。 使用Intellij IDEA 解決Java8的數據流問題 原文:Fixing Java 8 Stream Gotchas with IntelliJ IDEA 譯者:飛龍 協議:CC BY-NC-SA 4.0 ...
大概一年多之前,我對java8的理解還僅限一些只言片語的文章之上,后來出于對函數式編程的興趣,買了本參考書看了一遍,然后放在了書架上,后來,當我接手大客戶應用的開發工作之后,java8的一些工具,對我的效率有了不小的提升,因此想記錄一下java8的一些常用場景,我希望這會成為一個小字典,能讓我免于頻繁翻書,但是總能找到自己想找的知識。 用于舉例的model: @Data public class ...
閱讀 1641·2019-08-30 15:44
閱讀 2565·2019-08-30 11:19
閱讀 393·2019-08-30 11:06
閱讀 1556·2019-08-29 15:27
閱讀 3077·2019-08-29 13:44
閱讀 1621·2019-08-28 18:28
閱讀 2352·2019-08-28 18:17
閱讀 1978·2019-08-26 10:41