Stream中的Peek操作代碼
peek()是一個(gè)Intermediate操作,它接收一個(gè)Consumer類型的lambda參數(shù)(void類型),對(duì)每個(gè)元素執(zhí)行操作并返回一個(gè)新的Stream,并可以繼續(xù)進(jìn)行流的操作。peek()方法不會(huì)影響原始流中的元素。
1.引言
如果你試圖對(duì)流操作中的流水線進(jìn)行調(diào)試, 了解stream流水線每個(gè)操作之前和操作之后的中間值, 該如何去做?
首先我們看一個(gè)例子, 使用forEach將流操作的結(jié)果打印出來(lái).
/**
* @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操作, 整個(gè)流就會(huì)恢復(fù)運(yùn)行.并不能很好的幫助我們了解Stream流水線中的每個(gè)操作(如:map,filter,limit等)產(chǎn)生的輸出.
再來(lái)看一個(gè)例子
/**
* @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中的值,卻沒(méi)有任何輸出.2.中間操作和終止操作
中間操作是流水線中的數(shù)據(jù)進(jìn)行加工的, 它是一個(gè)懶操作, 并不會(huì)馬上執(zhí)行, 需要等待有終止操作的時(shí)候才會(huì)執(zhí)行.
終止操作是Stream的啟動(dòng)操作, 當(dāng)有終止操作的時(shí)候, Stream才會(huì)真正的開始執(zhí)行.
因此, 這里可以解釋上面的peek操作是一個(gè)中間操作, 所以沒(méi)有任何輸出.
3.使用peek進(jìn)行debug操作
peek的設(shè)計(jì)初衷就是在流的每個(gè)元素恢復(fù)運(yùn)行之前的時(shí)候插入一個(gè)執(zhí)行操作. 它不想forEach那樣恢復(fù)整個(gè)流的運(yùn)行操作. 而是在一個(gè)元素上完成操作之后, 它只會(huì)將操作順承到流水線的下一個(gè)操作. 它能夠?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 04.peek和map的區(qū)別
使用peek操作流,流中的元素沒(méi)有改變。
/**
* @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可以通過(guò)上面兩個(gè)例子看出,map操作是對(duì)元素進(jìn)行了轉(zhuǎn)換。
注意:peek對(duì)一個(gè)對(duì)象進(jìn)行操作的時(shí)候,對(duì)象不變,但是可以改變對(duì)象里面的值.如下:
/**
* @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 0peek的定義
Stream<T> peek(Consumer<? super T> action);
peek方法接收一個(gè)Consumer的入?yún)? 了解λ表達(dá)式的應(yīng)該明白 Consumer的實(shí)現(xiàn)類應(yīng)該只有一個(gè)方法,該方法返回類型為void. 它只是對(duì)Stream中的元素進(jìn)行某些操作,但是操作之后的數(shù)據(jù)并不返回到Stream中,所以Stream中的元素還是原來(lái)的元素.
map的定義
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
map方法接收一個(gè)Function作為入?yún)? Function是有返回值的, 這就表示map對(duì)Stream中的元素的操作結(jié)果都會(huì)返回到Stream中去.
到此這篇關(guān)于Stream中的Peek操作的文章就介紹到這了,更多相關(guān)Stream Peek操作內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Eclipse遠(yuǎn)程debug的步驟與注意事項(xiàng)
今天小編就為大家分享一篇關(guān)于Eclipse遠(yuǎn)程debug的步驟與注意事項(xiàng),小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-03-03
關(guān)于synchronized有趣的同步問(wèn)題
今天小編就為大家分享一篇關(guān)于關(guān)于synchronized有趣的同步問(wèn)題,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-01-01
logback ThresholdFilter臨界值日志過(guò)濾器源碼解讀
這篇文章主要為大家介紹了logback ThresholdFilter臨界值日志過(guò)濾器源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11
Java Integer.valueOf()和Integer.parseInt()的區(qū)別說(shuō)明
這篇文章主要介紹了Java Integer.valueOf()和Integer.parseInt()的區(qū)別說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-08-08
Springboot集成Actuator監(jiān)控功能詳解
這篇文章主要介紹了Springboot集成Actuator監(jiān)控功能詳解,有時(shí)候我們想要實(shí)時(shí)監(jiān)控我們的應(yīng)用程序的運(yùn)行狀態(tài),比如實(shí)時(shí)顯示一些指標(biāo)數(shù)據(jù),觀察每時(shí)每刻訪問(wèn)的流量,或者是我們數(shù)據(jù)庫(kù)的訪問(wèn)狀態(tài)等等,這時(shí)候就需要Actuator了,需要的朋友可以參考下2023-09-09
Java實(shí)現(xiàn)的微信公眾號(hào)獲取微信用戶信息示例
這篇文章主要介紹了Java實(shí)現(xiàn)的微信公眾號(hào)獲取微信用戶信息,結(jié)合實(shí)例形式分析了Java微信公眾號(hào)獲取微信用戶信息相關(guān)原理、步驟與操作注意事項(xiàng),需要的朋友可以參考下2019-10-10
gRPC在Java中的實(shí)現(xiàn)與應(yīng)用詳解
gRPC是由Google開發(fā)的高性能、開源的通用遠(yuǎn)程過(guò)程調(diào)用(RPC)框架,本文將詳細(xì)介紹如何在Java中使用gRPC,包括服務(wù)定義、服務(wù)器端實(shí)現(xiàn)、客戶端調(diào)用以及一些高級(jí)特性,我們將通過(guò)代碼示例來(lái)幫助理解gRPC的工作原理,需要的朋友可以參考下2024-06-06

