1 引言
在我們的日常編程任務(wù)中,對(duì)于集合的制造和處理是必不可少的。當(dāng)我們需要對(duì)于集合進(jìn)行分組或查找的操作時(shí),需要用迭代器對(duì)于集合進(jìn)行操作,而當(dāng)我們需要處理的數(shù)據(jù)量很大的時(shí)候,為了提高性能,就需要使用到并行處理,這樣的處理方式是很復(fù)雜的。流可以幫助開發(fā)者節(jié)約寶貴的時(shí)間,讓以上的事情變得輕松。
2 流簡介
流到底是什么呢?簡要的定義為 “從支持?jǐn)?shù)據(jù)處理操作的源生成的元素序列”,接下來對(duì)于這個(gè)定義進(jìn)行簡要分析。
2.1 支持?jǐn)?shù)據(jù)處理操作
流的數(shù)據(jù)處理操作和數(shù)據(jù)庫的可以聲明式的指定分組或查找等功能支持類似,和函數(shù)式編程的思想一致,如 filter、map、reduce、find、match、sort 等操作,這些流操作可以串行執(zhí)行,也可以并行執(zhí)行。
2.2 源
流會(huì)使用一個(gè)提供數(shù)據(jù)的源,可以通過三種方式來創(chuàng)建對(duì)象流,一種是由集合對(duì)象創(chuàng)建流:
Listlist = Arrays.asList(111,222,333); Stream stream = list.stream();
一種是由數(shù)組創(chuàng)建流:
IntStream stream = Arrays.stream(new int(){111,222,333});
一種是由靜態(tài)方法 Stream.of () 創(chuàng)建流,底層還是 Arrays.stream ():
StreamStream stream = Stream.of(111, 222, 333); 從有序集合生成流時(shí)會(huì)保留原有的順序。由列表生成的流,其元素順序與列表一致。stream = Stream.of(111, 222, 333);
還有兩種特殊的流:
空流:Stream.empty ()
無限流:Stream.genarate ()
2.3 元素序列
流也可以和集合一樣訪問包含特定的元素類型的一組有序值,但是它們的主要目的不一樣,集合的主要目的是在于存儲(chǔ)和訪問元素,流的主要目的在于表達(dá)計(jì)算。
3 流的思想
流式思想和生產(chǎn)中的流水線具有異曲同工之妙,很多流模型都會(huì)返回一個(gè)流,這些模型都只負(fù)責(zé)它所需要做的事情,并不需要格外的內(nèi)存空間來存儲(chǔ)處理的結(jié)果。這些流模型可以被鏈接起來形成一個(gè)大的流水線,我們?cè)谶@個(gè)過程中不關(guān)注中間步驟的數(shù)據(jù)被如何處理,只需要使用整個(gè)流水線處理后的結(jié)果。接下來的代碼可以體現(xiàn)這種思想,代碼中以商品為例,我們要篩選出商品中體積大于 200 的前兩個(gè)商品的名字。 首先是商品類的定義:
public class Goods { private final String Name; private final Integer Volume; public Goods(String name, Integer volume) { Name = name; Volume = volume; } public String getName() { return Name; } public Integer getVolume() { return Volume; } }
接下來是商品集合的定義:
Listgoods = Arrays.asList(new Goods("土豆",10), new Goods("冰箱",900),new Goods("辦公椅",300));
接下來獲取我們想要的結(jié)果:
List這樣看來,通過流來處理我們的特定需求,是不是比使用集合的迭代要方便很多呢?twofoods = goods.stream()//獲取流 .filter(goods1 -> goods1.getVolume()>200)//篩選商品體積大于200的 .map(Goods::getName)//獲取商品名稱 .limit(2)//篩選頭兩個(gè)商品 .collect(Collectors.toList());//將結(jié)果保存在list中
4 流處理的特性
不存儲(chǔ)數(shù)據(jù)
不會(huì)改變數(shù)據(jù)源
只可被使用一次
這里我們使用一個(gè)測(cè)試類 StreamCharacteristic 來驗(yàn)證流處理的以上特性:
import org.springframework.util.Assert; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; public class StreamCharacteristic { public void test1(){ Listtest1 () 中的結(jié)果為 6,盡管我們對(duì)于 list 對(duì)象所生成的 Stream 流做了去重操作 distinct (),但是不影響數(shù)據(jù)源 list。 test2 () 中調(diào)用了兩次 stream.forEach 方法來打印每一個(gè)單詞,第二次調(diào)用時(shí),拋出了一個(gè) “java.lang.IllegalStateException” 異常:“stream has already been operated upon or closed”。這說明流不存儲(chǔ)數(shù)據(jù),遍歷完后這個(gè)流已經(jīng)被消費(fèi)掉了,而且流不可以重復(fù)使用。list = Arrays.asList(1,2,2,5,6,9); list.stream().distinct(); System.out.println(list.size()); } public void test2(){ List list = Arrays.asList("wms", "KA", "5.0"); Stream stream = list.stream(); stream.forEach(System.out::println); stream.forEach(System.out::println); } }
5 流操作與流的使用
將所有的流操作連接起來可以組合成一個(gè)管道,管道有兩類操作:中間操作和終端操作。
StreamAPI 常用的中間操作有:filter,map,limit,sorted,distinct。 StreamAPI 常用的終端操作有:forEach,count,collect。 在使用流的時(shí)候,主要需要三個(gè)要素:一個(gè)用來執(zhí)行查詢的數(shù)據(jù)源,用來形成一條流的流水線的中間操作鏈,一個(gè)能夠執(zhí)行流水線并能生成結(jié)果的終端操作。 下圖展示了流的整個(gè)操作流程:
6 總結(jié)
流是從支持?jǐn)?shù)據(jù)處理操作的源生成的元素序列
流的思想類似于生產(chǎn)中的流水線
流不存儲(chǔ)數(shù)據(jù),不改變數(shù)據(jù)源,只能被改變一次
流的操作主要分為中間操作和終端操作兩大類
審核編輯:劉清
-
處理器
+關(guān)注
關(guān)注
68文章
19890瀏覽量
235118 -
存儲(chǔ)器
+關(guān)注
關(guān)注
38文章
7649瀏覽量
167346 -
JAVA語言
+關(guān)注
關(guān)注
0文章
138瀏覽量
20692
原文標(biāo)題:聊一聊Java中的Steam流
文章出處:【微信號(hào):OSC開源社區(qū),微信公眾號(hào):OSC開源社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
從焊接角度聊一聊,設(shè)計(jì)PCB的5個(gè)建議

聊一聊消息隊(duì)列技術(shù)選型的7種消息場(chǎng)景

來聊一聊Altium中Fill,Polygon Pour,Plane的區(qū)別和用法
聊一聊stm32的低功耗調(diào)試
聊一聊7系列FPGA的供電部分
聊一聊平衡小車代碼的實(shí)現(xiàn)
聊一聊FPGA的片內(nèi)資源相關(guān)知識(shí)

聊一聊IIC總線設(shè)計(jì)
小米米聊2月19日停止服務(wù) 米聊宣布關(guān)閉服務(wù)器
米聊復(fù)活了 能維持多久?
聊一聊FPGA中的彩色轉(zhuǎn)灰度的算法
【職場(chǎng)雜談】與嵌入式物聯(lián)網(wǎng)架構(gòu)師聊一聊幾個(gè)話題

聊一聊華為云彈性公網(wǎng)IP的那些事兒

評(píng)論