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