Java 流式编程stream
目錄
- 什么是Stream?
- 怎么創(chuàng)建Stream?
- Stream的中間操作
- Stream的終端操作
什么是Stream?
Stream它并不是一個(gè)容器,它只是對(duì)容器的功能進(jìn)行了增強(qiáng),添加了很多便利的操作,例如查找、過(guò)濾、分組、排序等一系列的操作。并且有串行、并行兩種執(zhí)行模式,并行模式充分的利用了多核處理器的優(yōu)勢(shì),使用fork/join框架進(jìn)行了任務(wù)拆分,同時(shí)提高了執(zhí)行速度。簡(jiǎn)而言之,Stream就是提供了一種高效且易于使用的處理數(shù)據(jù)的方式。
- 特點(diǎn):
- Stream自己不會(huì)存儲(chǔ)元素。
- Stream的操作不會(huì)改變?cè)磳?duì)象。相反,他們會(huì)返回一個(gè)持有結(jié)果的新Stream。
- Stream 操作是延遲執(zhí)行的。它會(huì)等到需要結(jié)果的時(shí)候才執(zhí)行。也就是執(zhí)行終端操作的時(shí)候。
一個(gè)Stream的操作就如上圖,在一個(gè)管道內(nèi),分為三個(gè)步驟,第一步是創(chuàng)建Stream,從集合、數(shù)組中獲取一個(gè)流,第二步是中間操作鏈,對(duì)數(shù)據(jù)進(jìn)行處理。第三步是終端操作,用來(lái)執(zhí)行中間操作鏈,返回結(jié)果。
怎么創(chuàng)建Stream?
-
由集合創(chuàng)建:
Java8 中的 Collection 接口被擴(kuò)展,提供了兩個(gè)獲取流的方法,這兩個(gè)方法是default方法,也就是說(shuō)所有實(shí)現(xiàn)Collection接口的接口都不需要實(shí)現(xiàn)就可以直接使用:default Stream stream() : 返回一個(gè)順序流。
default Stream parallelStream() : 返回一個(gè)并行流。
例如:
-
由數(shù)組創(chuàng)建:
Java8 中的 Arrays 的靜態(tài)方法 stream() 可以獲取數(shù)組流:static Stream stream(T[] array): 返回一個(gè)流
重載形式,能夠處理對(duì)應(yīng)基本類(lèi)型的數(shù)組:
public static IntStream stream(int[] array)
public static LongStream stream(long[] array)
public static DoubleStream stream(double[] array)
- 由值創(chuàng)建:
可以使用靜態(tài)方法 Stream.of(), 通過(guò)顯示值 創(chuàng)建一個(gè)流。它可以接收任意數(shù)量的參數(shù)。
public static Stream of(T… values) : 返回一個(gè)流。
- 可以使用靜態(tài)方法 Stream.iterate() 和 Stream.generate()創(chuàng)建無(wú)限流。
迭代
public static Stream iterate(final T seed, final UnaryOperator f)
生成
public static Stream generate(Supplier s)
注意:使用無(wú)限流一定要配合limit截?cái)?#xff0c;不然會(huì)無(wú)限制創(chuàng)建下去。
Stream的中間操作
如果Stream只有中間操作是不會(huì)執(zhí)行的,當(dāng)執(zhí)行終端操作的時(shí)候才會(huì)執(zhí)行中間操作,這種方式稱(chēng)為延遲加載或惰性求值。多個(gè)中間操作組成一個(gè)中間操作鏈,只有當(dāng)執(zhí)行終端操作的時(shí)候才會(huì)執(zhí)行一遍中間操作鏈,具體是因?yàn)槭裁次覀冊(cè)诤竺嬖僬f(shuō)明。下面看下Stream有哪些中間操作。
-
Stream distinct():
去重,通過(guò)流所生成元素的 hashCode() 和 equals() 去除重復(fù)元素。
-
Stream filter(Predicate<? super T> predicate):
Predicate函數(shù),它是斷言型接口,所以filter方法中是接收一個(gè)和Predicate函數(shù)對(duì)應(yīng)Lambda表達(dá)式,返回一個(gè)布爾值,從流中過(guò)濾某些元素。
-
Stream sorted(Comparator<? super T> comparator):
指定比較規(guī)則進(jìn)行排序。
-
Stream limit(long maxSize):
截?cái)嗔?#xff0c;使其元素不超過(guò)給定數(shù)量。如果元素的個(gè)數(shù)小于maxSize,那就獲取所有元素。
-
Stream skip(long n):
-
Stream map(Function<? super T, ? extends R> mapper):
接收一個(gè)Function函數(shù)作為參數(shù),該函數(shù)會(huì)被應(yīng)用到每個(gè)元素上,并將其映射成一個(gè)新的元素。也就是轉(zhuǎn)換操作,map還有三個(gè)應(yīng)用于具體類(lèi)型方法,分別是:mapToInt,mapToLong和mapToDouble。這三個(gè)方法也比較好理解,比如mapToInt就是把原始Stream轉(zhuǎn)換成一個(gè)新的Stream,這個(gè)新生成的Stream中的元素都是int類(lèi)型。這三個(gè)方法可以免除自動(dòng)裝箱/拆箱的額外消耗。
-
Stream flatMap(Function<? super T, ? extends Stream<? extends R>> mapper):
接收一個(gè)Function函數(shù)作為參數(shù),將流中的每個(gè)值都轉(zhuǎn)換成另一個(gè)流,然后把所有流連接成一個(gè)流。flatMap也有三個(gè)應(yīng)用于具體類(lèi)型的方法,分別是:flatMapToInt、flatMapToLong、flatMapToDouble,其作用于map的三個(gè)衍生方法相同。
Stream的終端操作
終端操作執(zhí)行中間操作鏈,并返回結(jié)果。終端操作我們就不一一介紹了,只介紹一下常用的操作。詳細(xì)可看java.util.stream.Stream接口中的方法。
- void forEach(Consumer<? super T> action):
-內(nèi)部迭代(需要用戶(hù)去做迭代,稱(chēng)為外部迭代。相反,Stream API使用內(nèi)部迭代幫你把迭代做了)
- <R, A> R collect(Collector<? super T, A, R> collector):
收集、將流轉(zhuǎn)換為其他形式,比如轉(zhuǎn)換成List、Set、Map。collect方法是用Collector作為參數(shù),Collector接口中方法的實(shí)現(xiàn)決定了如何對(duì)流執(zhí)行收集操作(如收集到 List、Set、Map)。但是 Collectors 實(shí)用類(lèi)提供了很多靜態(tài)方法,可以方便地創(chuàng)建常見(jiàn)收集器實(shí)例。例舉一些常用的:
-
其他終端操作:
- boolean allMatch(Predicate<? super T> predicate); 檢查是否匹配所有元素。
- boolean anyMatch(Predicate<? super T> predicate); 檢查是否至少匹配一個(gè)元素。
- boolean noneMatch(Predicate<? super T> predicate); 檢查是否沒(méi)有匹配所有元素。
- Optional findFirst(); 返回當(dāng)前流中的第一個(gè)元素。
- Optional findAny(); 返回當(dāng)前流中的任意元素。
- long count(); 返回流中元素總數(shù)。
- Optional max(Comparator<? super T> comparator); 返回流中最大值。
- Optional min(Comparator<? super T> comparator); 返回流中最小值。
- T reduce(T identity, BinaryOperator accumulator); 可以將流中元素反復(fù)結(jié)合起來(lái),得到一個(gè)值。 返回 T。這是一個(gè)歸約操作。
總結(jié)
以上是生活随笔為你收集整理的Java 流式编程stream的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: linux驱动加载模块可以用哪个命令(l
- 下一篇: Java 泛型实现方法 — 擦拭法