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

6 總結(jié)
- 流是從支持?jǐn)?shù)據(jù)處理操作的源生成的元素序列
- 流的思想類似于生產(chǎn)中的流水線
- 流不存儲(chǔ)數(shù)據(jù),不改變數(shù)據(jù)源,只能被改變一次
- 流的操作主要分為中間操作和終端操作兩大類
以上就是聊一聊Java中的Steam流的詳細(xì)內(nèi)容,更多關(guān)于Java Steam流的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
java基于數(shù)據(jù)庫(kù)實(shí)現(xiàn)全局唯一ID的示例
本文主要介紹了java基于數(shù)據(jù)庫(kù)實(shí)現(xiàn)全局唯一ID的示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04
Java中使用Hutool進(jìn)行AES加密解密的方法舉例
AES是一種對(duì)稱加密,所謂對(duì)稱加密就是加密與解密使用的秘鑰是一個(gè),下面這篇文章主要介紹了Java中使用Hutool進(jìn)行AES加密解密的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-04-04
深入Java7的一些新特性以及對(duì)腳本語(yǔ)言支持API的介紹
本篇文章是對(duì)Java7的一些新特性以及對(duì)腳本語(yǔ)言支持API的概述,需要的朋友參考下2013-05-05
spring cloud實(shí)現(xiàn)Eureka注冊(cè)中心的HA的方法
本篇文章主要介紹了spring cloud實(shí)現(xiàn)Eureka注冊(cè)中心的HA的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-01-01
springboot中@RestController注解實(shí)現(xiàn)
在JavaWeb開發(fā)中,Spring框架及其組件SpringMVC因高效和強(qiáng)大功能而廣受歡迎,@RestController注解是SpringMVC中的重要組成部分,下面就來(lái)介紹一下,感興趣的可以了解一下2024-09-09
Java利用Spire.XLS for Java輕松獲取Excel工作表的名稱
在日常的數(shù)據(jù)處理和自動(dòng)化報(bào)告場(chǎng)景中,我們經(jīng)常需要與 Excel 文件打交道,本文將深入探討如何利用功能強(qiáng)大的 Spire.XLS for Java 庫(kù)獲取普通可見工作表的名稱,有需要的小伙伴可以了解下2025-10-10

