java streams_使用Stream.peek在Java Streams内部进行窥视
java streams
對于剛接觸JDK 8的管道和流的Java開發(fā)人員而言, Stream接口提供的peek(Consumer)方法可以是有用的工具,有助于可視化流操作的行為。 即使是更熟悉Java流和聚合操作的Java開發(fā)人員,有時也會發(fā)現(xiàn)Stream.peek(Consumer)對于理解復(fù)雜的中間流操作的含義和交互作用很有用。
Stream.peek(Consumer)方法需要使用Consumer ,它實際上是一個接受單個參數(shù)卻不返回任何內(nèi)容的代碼塊。 peek(Consumer)方法返回傳遞給它的流的相同元素,因此除非傳遞給peek(Consumer)方法的代碼塊使流中的對象發(fā)生突變,否則流的內(nèi)容將不會更改。 。 Stream.peek(Consumer)的絕大多數(shù)用途可能是在調(diào)用該方法時以只讀方式打印流中對象的內(nèi)容。
Stream.peek(Consumer)的基于Javadoc的API文檔更加詳細(xì)地說明了此方法的行為,并提供了其用法示例。 該示例在下面的代碼清單中略作修改:
final List<String> strings= Stream.of("one", "two", "three", "four").peek(e-> out.println("Original Element: " + e)).filter(e -> e.length() > 3).peek(e -> out.println("Filtered value: " + e)).map(String::toUpperCase).peek(e -> out.println("Mapped value: " + e)).collect(Collectors.toList()); out.println("Final Results: " + strings);執(zhí)行上述代碼后,其關(guān)聯(lián)的輸出如下所示:
Original Element: one Original Element: two Original Element: three Filtered value: three Mapped value: THREE Original Element: four Filtered value: four Mapped value: FOUR Final Results: [THREE, FOUR]輸出通過提供給它們的元素講述了流操作的故事。 首次執(zhí)行中間peek操作將使用前綴“原始元素:”將原始流中的每個元素寫到系統(tǒng)輸出中。 對于每個原始String不會執(zhí)行稍后發(fā)生的中間peek操作的實例,因為這些peek操作中的每一個都至少在進(jìn)行一次過濾之后發(fā)生。
啟用peek輸出還清楚地顯示了在每個String元素上以等效的大寫形式執(zhí)行中間操作映射的結(jié)果。 收集操作是終止操作,因此此后不進(jìn)行任何peek 。 peek操作的戰(zhàn)略位置可讓您深入了解正在發(fā)生的流處理。
用于Stream.peek(Consumer)的Javadoc指出:“存在此方法主要是為了支持調(diào)試,您需要在其中查看元素流過管道中特定點的情況。” 這正是上面顯示的示例和輸出所演示的,并且可能是Stream.peek(Consumer)的最常見應(yīng)用。
Stream.peek(Consumer)的Javadoc文檔以以下描述性句子開頭:“返回由該流的元素組成的流,并在從結(jié)果流中消耗掉元素時對每個元素執(zhí)行附加的操作。” 在前面的示例中,在消耗每個元素時對每個元素執(zhí)行的操作只是將其字符串表示形式寫入標(biāo)準(zhǔn)輸出。 但是,采取的操作可以是可以指定為Consumer任何內(nèi)容(任何接受單個參數(shù)且不返回任何參數(shù)的代碼塊)。 下一個示例演示如何甚至可以使用peek(Consumer)更改流上對象的內(nèi)容。
在本文的第一個示例中, peek(Consumer)無法更改流元素,因為這些元素是不可變的Java String 。 然而,如果流元件是可變的,則Consumer傳遞給peek(Consumer)可以改變這些元素的含量。 為了說明這一點,我將使用MutablePerson顯示的簡單類MutablePerson 。
MutablePerson.java
package dustin.examples.jdk8.streams;/*** Represents person whose name can be changed.*/ public class MutablePerson {private String name;public MutablePerson(final String newName){name = newName;}public String getName(){return name;}public void setName(final String newName){name = newName;}@Overridepublic String toString(){return name;} }下一個代碼清單顯示了當(dāng)該流中的元素可變時, Stream.peek(Consumer)如何更改該流操作的結(jié)果。
final List<MutablePerson> people= Stream.of(new MutablePerson("Fred"),new MutablePerson("Wilma"),new MutablePerson("Barney"),new MutablePerson("Betty")).peek(person -> out.println(person)).peek(person -> person.setName(person.getName().toUpperCase())).collect(Collectors.toList()); out.println("People: " + people);執(zhí)行上述代碼后,它會產(chǎn)生如下輸出:
Fred Wilma Barney Betty People: [FRED, WILMA, BARNEY, BETTY]此示例表明,傳遞給peek的Consumer確實將人民姓名的大小寫更改為大寫。 這僅是可能的,因為正在處理的對象是可變的。 有人認(rèn)為使用peek更改流中的元素可能是一種反模式 ,我發(fā)現(xiàn)自己對此方法感到不舒服(但我通常也不喜歡將方法的參數(shù)設(shè)為“ 輸出參數(shù) ”)。 peek方法的名稱peek一個人只是看(而不是觸摸),但是它接受的Consumer參數(shù)則宣告可以更改某些內(nèi)容( Consumer的Javadoc指出,“與大多數(shù)其他功能接口不同,Consumer應(yīng)該通過副作用來操作” )。 博客文章“ 使用Java Stream API進(jìn)行Stream.peek(Consumer) ”討論了使用Stream.peek(Consumer)和變異操作相關(guān)的潛在問題。
Steam.peek(Consumer)是用于了解流操作如何影響元素的有用工具。
翻譯自: https://www.javacodegeeks.com/2018/06/peeking-inside-java-streams.html
java streams
總結(jié)
以上是生活随笔為你收集整理的java streams_使用Stream.peek在Java Streams内部进行窥视的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何在电脑上查看照片流里的照片(怎么查看
- 下一篇: rpc服务器不可用(rpc服务器不可用怎