? ? ?在軟件行業(yè)里面,關(guān)于是否需要重復(fù)造輪子,一直是一個討論的問題?我個人是一個喜歡重復(fù)造輪子的人,并不是我不相信開源項目里的“輪子”,而是我想學習一下別人的思想是什么?關(guān)于“輪子”我們一直是使用者,也是學習造輪子的技術(shù)的學習者。一直被別人討論為閉門造輪子,但是我一直都不認為我是一個閉門造輪子的人。一直都在借鑒別人和學習別人。
? ? ? ? JDK1.8從發(fā)布到現(xiàn)在已經(jīng)有二年多時間了!但是對于我們而言,我們一直使用JDK1.6,JDK1.7,其實不是我們不想使用JDK1.8。而是我們的開發(fā)人員對于1.8的特性了解不是很多。即使1.7的特使我們都沒有使用多少新特性,別說1.8了。即使使用1.8,但是我們還在使用1.7的特性,那么和1.7其實沒有多大的必要。
聊聊1.8的新特性吧!
1:接口改善
2:函數(shù)式接口
3:Lambdas
4:java.util.function
5:java.util.stream
6:泛型接口改進
7:java.time
8:集合API附件
9:增加并發(fā)API
10:IO/NIO API的新增內(nèi)容
11:反射和annotation的改動
12:Nashorn JavaScript 引擎
? ? ? ? 對于一個Java開發(fā)人員而言,其實每一次JDK發(fā)布新的標準的時候,我往往是欣喜若狂,因為不同的標準出現(xiàn),你就會發(fā)現(xiàn),你將為之少付出很多時間去實現(xiàn)一個以前需要花很長時間的功能了。但是其實我個人思考的是,其實隨著各種規(guī)范出現(xiàn),是否我們都要去實現(xiàn),我個人其實不是很喜歡,我只喜歡根據(jù)這些規(guī)范我準備實現(xiàn)什么,我準備為這些規(guī)范如何在哪些模塊準備以一種什么樣的方式實現(xiàn)它。
說說正題吧!
? ? ? ? 眾所周知Java8中加入了lambda語法,這一特性也幫助Java開發(fā)者極大的簡化了開發(fā)。相對于Java世界的ORM框架的話,我們有JPA,Hibernate,Mybatis等等一些被認可的很好的ORM框架。但是當Jdk1.8出現(xiàn),lambda和stream是否可以組合成一個新的ORM架構(gòu)呢?現(xiàn)在市面上已經(jīng)有了Speedment框架就是使用lambda表達式操作數(shù)據(jù)庫的框架。當我想做這個的時候,Speedment版本不知道迭代了多少版本!我不認為我做的有Speedment那么好,但是我肯定可以通過這個可以更加方便理解lambda和stream。
先來一個簡單的數(shù)據(jù)集存儲在List里面,然后從List中搜索想要的數(shù)據(jù)吧!
? ? ? ? 一開始沒法做的那么復(fù)雜,只能通過簡單List先理解lambda和stream。因為我個人認為只有這樣才能進一步的了解和編寫想要的。
List<String> list = new ArrayList<>();
List?test = list.stream().
filter(module -> module.equals("1")).
filter(module -> module.equals("2")).
collect(Collectors.toList());
? ? ? ?對于我個人而言其實第一步就是如何集成Stram接口和重寫里面的方法。因為我認為filter其實就是我們的查詢條件。但是對于數(shù)據(jù)庫我們有Join等等一些列SQL的寫法。
在這個開發(fā)過程中對于Stream理解是一個很大的挑戰(zhàn),我們來看看IBM上面對于Stream介紹吧!
為什么需要 Stream
? ? ? ?Stream 作為 Java 8 的一大亮點,它與 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念。它也不同于 StAX 對 XML 解析的 Stream,也不是 Amazon Kinesis 對大數(shù)據(jù)實時處理的 Stream。Java 8 中的 Stream 是對集合(Collection)對象功能的增強,它專注于對集合對象進行各種非常便利、高效的聚合操作(aggregate operation),或者大批量數(shù)據(jù)操作 (bulk data operation)。Stream API 借助于同樣新出現(xiàn)的 Lambda 表達式,極大的提高編程效率和程序可讀性。同時它提供串行和并行兩種模式進行匯聚操作,并發(fā)模式能夠充分利用多核處理器的優(yōu)勢,使用 fork/join 并行方式來拆分任務(wù)和加速處理過程。通常編寫并行代碼很難而且容易出錯, 但使用 Stream API 無需編寫一行多線程的代碼,就可以很方便地寫出高性能的并發(fā)程序。所以說,Java 8 中首次出現(xiàn)的 java.util.stream 是一個函數(shù)式語言+多核時代綜合影響的產(chǎn)物。
什么是聚合操作
在傳統(tǒng)的 J2EE 應(yīng)用中,Java 代碼經(jīng)常不得不依賴于關(guān)系型數(shù)據(jù)庫的聚合操作來完成諸如:
1:客戶每月平均消費金額
2:最昂貴的在售商品
3:本周完成的有效訂單(排除了無效的)
4:取十個數(shù)據(jù)樣本作為首頁推薦
這類的操作。
但在當今這個數(shù)據(jù)大爆炸的時代,在數(shù)據(jù)來源多樣化、數(shù)據(jù)海量化的今天,很多時候不得不脫離 RDBMS,或者以底層返回的數(shù)據(jù)為基礎(chǔ)進行更上層的數(shù)據(jù)統(tǒng)計。而 Java 的集合 API 中,僅僅有極少量的輔助型方法,更多的時候是程序員需要用 Iterator 來遍歷集合,完成相關(guān)的聚合應(yīng)用邏輯。這是一種遠不夠高效、笨拙的方法。在 Java 7 中,如果要發(fā)現(xiàn) type 為 grocery 的所有交易,然后返回以交易值降序排序好的交易 ID 集合,我們需要這樣寫:


Java 8 使用 Stream,代碼更加簡潔易讀;而且使用并發(fā)模式,程序執(zhí)行速度更快。
Stream 總覽
什么是流
? ? ? ?Stream 不是集合元素,它不是數(shù)據(jù)結(jié)構(gòu)并不保存數(shù)據(jù),它是有關(guān)算法和計算的,它更像一個高級版本的 Iterator。原始版本的 Iterator,用戶只能顯式地一個一個遍歷元素并對其執(zhí)行某些操作;高級版本的 Stream,用戶只要給出需要對其包含的元素執(zhí)行什么操作,比如 “過濾掉長度大于 10 的字符串”、“獲取每個字符串的首字母”等,Stream 會隱式地在內(nèi)部進行遍歷,做出相應(yīng)的數(shù)據(jù)轉(zhuǎn)換。
? ? ? ? Stream 就如同一個迭代器(Iterator),單向,不可往復(fù),數(shù)據(jù)只能遍歷一次,遍歷過一次后即用盡了,就好比流水從面前流過,一去不復(fù)返。
? ? ? ? 而和迭代器又不同的是,Stream 可以并行化操作,迭代器只能命令式地、串行化操作。顧名思義,當使用串行方式去遍歷時,每個 item 讀完后再讀下一個 item。而使用并行去遍歷時,數(shù)據(jù)會被分成多個段,其中每一個都在不同的線程中處理,然后將結(jié)果一起輸出。Stream 的并行操作依賴于 Java7 中引入的 Fork/Join 框架(JSR166y)來拆分任務(wù)和加速處理過程。Java 的并行 API 演變歷程基本如下:
1:1.0-1.4 中的 java.lang.Thread
2:5.0 中的 java.util.concurrent
3:6.0 中的 Phasers 等
4:7.0 中的 Fork/Join 框架
5:8.0 中的 Lambda
Stream 的另外一大特點是,數(shù)據(jù)源本身可以是無限的。
流的構(gòu)成
當我們使用一個流的時候,通常包括三個基本步驟:
獲取一個數(shù)據(jù)源(source)→ 數(shù)據(jù)轉(zhuǎn)換→執(zhí)行操作獲取想要的結(jié)果,每次轉(zhuǎn)換原有 Stream 對象不改變,返回一個新的 Stream 對象(可以有多次轉(zhuǎn)換),這就允許對其操作可以像鏈條一樣排列,變成一個管道。

看看JDK1.8中Stream的API,你會發(fā)現(xiàn)一些你看的很熟悉的"東東"



具體很多請參考http://docs.oracle.com/javase/8/docs/api/index.html的介紹。
發(fā)現(xiàn)了什么?
夜已深,準備開始新的挑戰(zhàn),根據(jù)這些簡單的介紹,相信大家知道我準備怎么干了。即使這么做很傻。但是我還是這么做。