【java学习笔记】java se8的流库概念以及使用
- 概念
- 代碼實(shí)例
- 流的創(chuàng)建
- 惰性求值與及早求值
概念
流提供了一種讓我們可以在比集合更高的概念級(jí)別上指定計(jì)算的數(shù)據(jù)視圖。通過使用流,我們可以說明想要完成什么任務(wù),而不是說明如何去實(shí)現(xiàn)它。我們將操作的調(diào)度留給具體實(shí)現(xiàn)去解決。例如,假設(shè)我們想要計(jì)算某個(gè)屬性的平均值,那么我們就可以指定數(shù)據(jù)源和該屬性,然后,流庫就可以對(duì)計(jì)算進(jìn)行優(yōu)化,例如,使用多線程來計(jì)算總和與個(gè)數(shù),并將結(jié)果合并。它是在Java SE 8中引入的,用來以“做什么而非怎么做”的方式處理集合。
代碼實(shí)例
下面一個(gè)例子:
String contents = new String(Files,readAllBytes(Paths.get("mm.txt"), StandardCharsets.UTF_8));List<String>words = Arrays.asList(contents.split("\\PL+"));//long count = 0;for(String w:words){if(w.length()>12)count++;}//如果使用流,也可以用這樣的寫法long count = words.stream().filter(w->w.length()>12).count(); Stream<T> filter(Predicate<? super T> p) //產(chǎn)生一個(gè)流,其中包含當(dāng)前流中滿足P的所有元素。`·long count() 產(chǎn)生當(dāng)前流中元素的數(shù)量。這是一個(gè)終止操作。
java.util.Collection<E>1.2
·default Stream<E> stream()
·default Stream<E> parallelStream()
產(chǎn)生當(dāng)前集合中所有元素的順序流或并行流。
流表a面上看起來和集合很類似,都可以讓我們轉(zhuǎn)換和獲取數(shù)據(jù)。但是,它們之間存在著顯著的差異:
1.流并不存儲(chǔ)其元素。這些元素可能存儲(chǔ)在底層的集合中,或者是按需生成的。
2.流的操作不會(huì)修改其數(shù)據(jù)源。例如,filter方法不會(huì)從新的流中移除元素,而是會(huì)生成一個(gè)新的流,其中不包含被過濾掉的元素。
3.流的操作是盡可能惰性執(zhí)行的。這意味著直至需要其結(jié)果時(shí),操作才 會(huì)執(zhí)行。例如,如果我們只想查找前5個(gè)長(zhǎng)單詞而不是所有長(zhǎng)單詞,那么filter方法就會(huì)在匹配到第5個(gè)單詞后停止過濾。因此,我們甚至可以操作無限流。
操作流時(shí)的典型流程:建立一個(gè)包含三個(gè)階段的操作管道:
1.創(chuàng)建一個(gè)流。 2.指定將初始流轉(zhuǎn)換為其他流的中間操作,可能包含多個(gè)步驟。 3.應(yīng)用終止操作,從而產(chǎn)生結(jié)果。這個(gè)操作會(huì)強(qiáng)制執(zhí)行之前的惰性操作。從此之后,這個(gè)流就再也不能用了。也可以用parallelStream方法創(chuàng)建并行流
流的創(chuàng)建
可以用Collection接口的stream方法將任何集合轉(zhuǎn)換為一個(gè)流。如果你有一個(gè)數(shù)組,那么可以使用靜態(tài)的Stream.of方法。
Stream<String>words = Stream.of(contends.split("\\pl+");//split returns a String[] arrayof方法具有可變長(zhǎng)參數(shù),因此我們可以構(gòu)建具有任意數(shù)量引元的流:
Stream<String>words = Stream.of("my","you","and");使用Array.stream(array,from,to)可以從數(shù)組中位于from(包括)和to(不包括)的元素中創(chuàng)建一個(gè)流。
為了創(chuàng)建不包含任何元素的流,可以使用靜態(tài)的Stream.empty方法:
Stream接口有兩個(gè)用于創(chuàng)建無限流的靜態(tài)方法。generate方法會(huì)接受一個(gè)不包含任何引元的函數(shù)(或者從技術(shù)上講,是一個(gè)Supplier<T>接口的對(duì)象)
Stream<String>echos = Stream.generate(()->"Echo");static <T> Stream<T> generate(Supplier<T> s)
Where, Stream is an interface and T is the type of stream elements. s
is the Supplier of generated elements and the return value is a new
infinite sequential unordered Stream.
我們可以像下面這樣獲得一個(gè)常量值的流: 或者像下面這樣獲取一個(gè)隨機(jī)數(shù)的流:
public static void main(String[] args) {Stream.generate(new Random()::nextInt).limit(5).forEach(System.out::println);}輸出
-1891038009
-1978949720
107075108
196723573
2041949678
惰性求值與及早求值
惰性求值:只描述Stream,操作的結(jié)果也是Stream,這樣的操作稱為惰性求值。惰性求值可以像建造者模式一樣鏈?zhǔn)绞褂?#xff0c;最后再使用及早求值得到最終結(jié)果。
及早求值:得到最終的結(jié)果而不是Stream,這樣的操作稱為及早求值。
filter的引元是Predicate/,即從T到boolean的函數(shù)。 通常,我們想要按照某種方式來轉(zhuǎn)換流中的值,此時(shí),可以使用map方法并傳遞執(zhí)行該轉(zhuǎn)換的函數(shù)
map
轉(zhuǎn)換功能,內(nèi)部就是Function接口。惰性求值。例如,
流的轉(zhuǎn)換會(huì)產(chǎn)生一個(gè)新的流,它的元素派生自另一個(gè)流中的元素。我們已經(jīng)看到了filter轉(zhuǎn)換會(huì)產(chǎn)生一個(gè)流,它的元素與某種條件相匹配。如上面的一個(gè)代碼,我們將一個(gè)字符串流轉(zhuǎn)換為了只包含長(zhǎng)單詞的另一個(gè)流
我們可以像下面這樣將所有單詞都轉(zhuǎn)換為小寫:
這里,我們使用的是帶有方法引用的map,但是,通常我們可以使用lambda表達(dá)式來代替:
Stream<String>firstLetters = words.stream().map(s->s.substring(0,1) //產(chǎn)生的流中包含了所有單詞的首字母·Stream<T>filter(Predicate<?super T>predicate)
產(chǎn)生一個(gè)流,它包含當(dāng)前流中所有滿足斷言條件的元素。 ·<R>Stream<R>map(Function<?super
T,?extends R>mapper) 產(chǎn)生一個(gè)流,它包含將mapper應(yīng)用于當(dāng)前流中所有元素所產(chǎn)生的結(jié)果。
·<R>Stream<R>flatMap(Function<?super T,?extends Stream<?extends
R>>mapper)
產(chǎn)生一個(gè)流,它是通過將mapper應(yīng)用于當(dāng)前流中所有元素所產(chǎn)生的結(jié)果連接到一起而獲得的。(注意,這里的每個(gè)結(jié)果都是一個(gè)流。)
flatmap
多個(gè)stream合并為一個(gè)stream
調(diào)用Stream.of的靜態(tài)方法將兩個(gè)list轉(zhuǎn)換為Stream,再通過flatMap將兩個(gè)流合并為一個(gè)。
max和min
我們經(jīng)常會(huì)在集合中求最大或最小值,使用流就很方便。及早求值。
max、min接收一個(gè)Comparator(例子中使用java8自帶的靜態(tài)函數(shù),只需要傳進(jìn)需要比較值即可。)并且返回一個(gè)Optional對(duì)象,該對(duì)象是java8新增的類,專門為了防止null引發(fā)的空指針異常。
reduce
reduce 操作可以實(shí)現(xiàn)從一組值中生成一個(gè)值。在上述例子中用到的 count 、 min 和 max 方法,因?yàn)槌S枚患{入標(biāo)準(zhǔn)庫中。事實(shí)上,這些方法都是 reduce 操作。及早求值。
輸出15
總結(jié)
以上是生活随笔為你收集整理的【java学习笔记】java se8的流库概念以及使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 过程记录 yolov3目标检测输出目标坐
- 下一篇: 【spring相关面试题摘录】