一、Stream簡介
在介紹Java Stream Peek之前,先需要了解Java Stream的概念。Java Stream是在Java 8之後引入的一種新的處理數據集合的方式,它可以更簡便、高效地操作集合中的數據。與傳統的集合操作方式相比,Java Stream可以提高性能和代碼可讀性。
Java Stream是一個表示任意元素序列的概念,它支持各種類型的數據源,例如List、Set、數組等,Stream操作可以分為中間操作和終端操作兩類。中間操作包括過濾、映射、排序、去重等操作,而終端操作包括forEach、count、collect等。
二、Stream Peek的作用
Stream Peek是Stream中的一個中間操作,它可以讓我們在Stream中執行一些診斷性的操作,例如打印出Stream中的元素、記錄日誌、計算執行時間等。Stream Peek可以幫助我們更好地了解Stream的數據流向,也可以在調試代碼時提供一些幫助。
Stream Peek的簽名如下:
Stream peek(Consumer action);
其中,action代表一個Consumer類型的函數式接口,它可以在Stream的每個元素上執行一些操作。
三、Stream Peek的使用場景
Stream Peek適用於以下一些場景:
1、觀察Stream的數據流向
在對Stream進行多個操作時,我們有時難以確定Stream中數據的真實狀態,即Stream中的元素究竟是什麼樣子的。此時,可以在每個中間操作之後插入一個peek操作,打印出當前Stream中的元素,以便我們觀察Stream的數據流向。例如:
List<String> list = Arrays.asList("apple", "banana", "orange", "watermelon"); list.stream().filter(s -> s.length() > 5) .peek(s -> System.out.println("filter:" + s)) .map(String::toUpperCase) .peek(s -> System.out.println("toUpperCase:" + s)) .collect(Collectors.toList());
執行結果如下:
filter:orange toUpperCase:ORANGE filter:watermelon toUpperCase:WATERMELON
打印出了Stream中經過過濾和映射之後的元素,以便我們更清楚地了解Stream的數據流向。
2、記錄日誌
在開發中,我們經常需要記錄一些日誌信息以便追蹤問題。Stream Peek可以方便地記錄一些Stream中的信息。例如,在以下的示例中,我們在Stream Peek中打印出當前處理的數字:
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); list.stream().peek(i -> System.out.println("processing:" + i)) .map(i -> i * 2) .peek(i -> System.out.println("result:" + i)) .collect(Collectors.toList());
執行結果如下:
processing:1 result:2 processing:2 result:4 processing:3 result:6 processing:4 result:8 processing:5 result:10
可以看到,在Stream Peek中,我們輸出了每個數字的處理過程和結果,方便我們日後進行追蹤和調試。
四、Stream Peek的注意事項
當使用Stream Peek時,需要注意以下事項:
1、Stream Peek是中間操作
與終端操作不同,Stream Peek是中間操作,它不能打斷Stream的處理過程。如果在Stream Peek中拋出異常,那麼Stream的處理將會中斷。
2、Stream Peek不能修改Stream中的元素
Stream Peek只是對Stream中的元素進行一些操作,它不能修改Stream中的元素。如果需要對Stream進行修改,應該使用map等終端操作。
3、Stream Peek可以執行多次
與終端操作不同,Stream Peek是可以執行多次的,每次執行都會打印出當前Stream中的元素。例如:
List<String> list = Arrays.asList("apple", "banana", "orange", "watermelon"); Stream<String> stream = list.stream(); stream.peek(s -> System.out.println("peek1:" + s)) .filter(s -> s.length() > 5) .peek(s -> System.out.println("peek2:" + s)) .map(String::toUpperCase) .peek(s -> System.out.println("peek3:" + s)) .collect(Collectors.toList()); stream.peek(s -> System.out.println("peek4:" + s)) .map(String::toLowerCase) .peek(s -> System.out.println("peek5:" + s)) .collect(Collectors.toList());
執行結果如下:
peek1:apple peek1:banana peek1:orange peek1:watermelon peek2:watermelon peek3:WATERMELON peek2:orange peek3:ORANGE peek4:apple peek4:banana peek4:orange peek4:watermelon peek5:orange peek5:watermelon peek5:apple peek5:banana
可以看到,在兩個不同的Stream中執行了多個peek操作。
五、代碼示例
以下為一個完整的Java Stream Peek的代碼示例:
import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; public class StreamPeekExample { public static void main(String[] args) { // 觀察Stream的數據流向 List<String> list = Arrays.asList("apple", "banana", "orange", "watermelon"); list.stream().filter(s -> s.length() > 5) .peek(s -> System.out.println("filter:" + s)) .map(String::toUpperCase) .peek(s -> System.out.println("toUpperCase:" + s)) .collect(Collectors.toList()); // 記錄日誌 List<Integer> list2 = Arrays.asList(1, 2, 3, 4, 5); list2.stream().peek(i -> System.out.println("processing:" + i)) .map(i -> i * 2) .peek(i -> System.out.println("result:" + i)) .collect(Collectors.toList()); // 可以執行多次 Stream<String> stream = list.stream(); stream.peek(s -> System.out.println("peek1:" + s)) .filter(s -> s.length() > 5) .peek(s -> System.out.println("peek2:" + s)) .map(String::toUpperCase) .peek(s -> System.out.println("peek3:" + s)) .collect(Collectors.toList()); stream.peek(s -> System.out.println("peek4:" + s)) .map(String::toLowerCase) .peek(s -> System.out.println("peek5:" + s)) .collect(Collectors.toList()); } }
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/308791.html