Stream中的Peek操作代碼
peek()是一個Intermediate操作,它接收一個Consumer類型的lambda參數(shù)(void類型),對每個元素執(zhí)行操作并返回一個新的Stream,并可以繼續(xù)進行流的操作。peek()方法不會影響原始流中的元素。
1.引言
如果你試圖對流操作中的流水線進行調(diào)試, 了解stream流水線每個操作之前和操作之后的中間值, 該如何去做?
首先我們看一個例子, 使用forEach將流操作的結(jié)果打印出來.
/** * @author lyh * @version v-1.0.0 * @since 2021/5/28 */ public class PeekTestOne { public static void main(String[] args) { List<Integer> list = Arrays.asList(4, 7, 9, 11, 12); list.stream() .map(x -> x + 2) .filter(x -> x % 2 != 0) .limit(2) .forEach(System.out::println); } } 輸出結(jié)果如下: 9 11
可以很明顯的看出, 一旦調(diào)用了forEach操作, 整個流就會恢復(fù)運行.并不能很好的幫助我們了解Stream流水線中的每個操作(如:map,filter,limit等)產(chǎn)生的輸出.
再來看一個例子
/** * @author lyh * @version v-1.0.0 * @since 2021/5/28 */ public class PeekTestTwo { public static void main(String[] args) { Stream<Integer> stream = Arrays.asList(4, 7, 9, 11, 12).stream(); stream.peek(System.out::println); } } 這段代碼是想打印stream中的值,卻沒有任何輸出.
2.中間操作和終止操作
中間操作是流水線中的數(shù)據(jù)進行加工的, 它是一個懶操作, 并不會馬上執(zhí)行, 需要等待有終止操作的時候才會執(zhí)行.
終止操作是Stream的啟動操作, 當(dāng)有終止操作的時候, Stream才會真正的開始執(zhí)行.
因此, 這里可以解釋上面的peek操作是一個中間操作, 所以沒有任何輸出.
3.使用peek進行debug操作
peek的設(shè)計初衷就是在流的每個元素恢復(fù)運行之前的時候插入一個執(zhí)行操作. 它不想forEach那樣恢復(fù)整個流的運行操作. 而是在一個元素上完成操作之后, 它只會將操作順承到流水線的下一個操作. 它能夠?qū)⒅虚g變量的值輸出到日志. 有效的幫助我們了解流水線的每一步操作的輸出值.如下圖:
/** * @author lyh * @version v-1.0.0 * @since 2021/5/28 */ public class PeekTestThree { public static void main(String[] args) { List<Integer> list = Arrays.asList(4, 7, 9, 11, 12); list.stream() .peek(x -> System.out.println("stream: " + x)) .map(x -> x + 2) .peek(x -> System.out.println("map: " + x)) .filter(x -> x % 2 != 0) .peek(x -> System.out.println("filter: " + x)) .limit(2) .peek(x -> System.out.println("limit: " + x)) .collect(toList()); } } 輸出結(jié)果如下: stream: 4 map: 6 stream: 7 map: 9 filter: 9 limit: 9 stream: 9 map: 11 filter: 11 limit: 11 Process finished with exit code 0
4.peek和map的區(qū)別
使用peek操作流,流中的元素沒有改變。
/** * @author lyh * @version v-1.0.0 * @since 2021/5/28 */ public class PeekAndMapTestOne { public static void main(String[] args) { Arrays.asList("a","b") .stream() .peek(x -> x.toUpperCase()) .forEach(System.out::println); } } 輸出: a b Process finished with exit code 0
使用map操作流,流中的元素有改變。
/** * @author lyh * @version v-1.0.0 * @since 2021/5/28 */ public class PeekAndMapTestTwo { public static void main(String[] args) { Arrays.asList("a","b") .stream() .map(x -> x.toUpperCase()) .forEach(System.out::println); } } 輸出: A B Process finished with exit code 0
可以通過上面兩個例子看出,map操作是對元素進行了轉(zhuǎn)換。
注意:peek對一個對象進行操作的時候,對象不變,但是可以改變對象里面的值.如下:
/** * @author lyh * @version v-1.0.0 * @since 2021/5/28 */ @Getter @Setter @AllArgsConstructor @ToString public class Person { private String id; private String name; } ---------------------------------------------------------------------------- /** * @author lyh * @version v-1.0.0 * @since 2021/5/28 */ public class PeekAndMapTestThree { public static void main(String[] args) { Arrays.asList(new Person("001","zs"),new Person("002","ls")) .stream().peek(p -> p.setId("000")).forEach(System.out::println); } } 輸出: Person(id=000, name=zs) Person(id=000, name=ls) Process finished with exit code 0
peek的定義
Stream<T> peek(Consumer<? super T> action);
peek方法接收一個Consumer的入?yún)? 了解λ表達式的應(yīng)該明白 Consumer的實現(xiàn)類應(yīng)該只有一個方法,該方法返回類型為void. 它只是對Stream中的元素進行某些操作,但是操作之后的數(shù)據(jù)并不返回到Stream中,所以Stream中的元素還是原來的元素.
map的定義
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
map方法接收一個Function作為入?yún)? Function是有返回值的, 這就表示map對Stream中的元素的操作結(jié)果都會返回到Stream中去.
到此這篇關(guān)于Stream中的Peek操作的文章就介紹到這了,更多相關(guān)Stream Peek操作內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JVM實戰(zhàn)系列之CPU100%和內(nèi)存100%排查
本文主要介紹了JVM實戰(zhàn)系列之CPU100%和內(nèi)存100%排查,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06Java中的關(guān)鍵字synchronized 詳解
這篇文章主要介紹了Java中的關(guān)鍵字synchronized,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03Java超詳細(xì)分析講解final關(guān)鍵字的用法
關(guān)于final關(guān)鍵字,它也是我們一個經(jīng)常用的關(guān)鍵字,可以修飾在類上、或者修飾在變量、方法上,以此看來定義它的一些不可變性!像我們經(jīng)常使用的String類中,它便是final來修飾的類,并且它的字符數(shù)組也是被final所修飾的。但是一些final的一些細(xì)節(jié)你真的了解過嗎2022-06-06java開發(fā)gui教程之jframe監(jiān)聽窗體大小變化事件和jframe創(chuàng)建窗體
這篇文章主要介紹了java開發(fā)gui教程中jframe監(jiān)聽窗體大小變化事件和jframe創(chuàng)建窗體的示例,需要的朋友可以參考下2014-03-03Java異常處理之java.lang.ClassCastException問題
這篇文章主要介紹了Java異常處理之java.lang.ClassCastException問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-07-07Mybatis3中方法返回生成的主鍵:XML,@SelectKey,@Options詳解
這篇文章主要介紹了Mybatis3中方法返回生成的主鍵:XML,@SelectKey,@Options,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01