peek(窺視)和map(轉(zhuǎn)換)顧名思義:一個是看一眼參數(shù)菱父,一個是轉(zhuǎn)化參數(shù)。
1. 區(qū)別
peek和map的區(qū)別:均作為流處理的中間操作牙甫,但是兩個的內(nèi)部處理函數(shù)不同竞帽,一個為“消費元素”,另一個為“映射元素”汽烦。
Stream<T> peek(Consumer<? super T> action);
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
peek和foreach的區(qū)別:peek作為中間操作涛菠,而foreach作為終端操作;
Stream<T> peek(Consumer<? super T> action);
void forEach(Consumer<? super T> action);
2. peek的使用場景
在Java doc中這樣描述:“元素存在的目的為了進行debug”
API Note:
This method exists mainly to support debugging, where you want to see the elements as they flow past a certain point in a pipeline:
那么能否使用peek做其他操作呢撇吞?
例如:對內(nèi)部的元素進行修改俗冻。
public class TestPeek {
public static void main(String[] args) {
List<User> lists = new ArrayList<>();
lists.add(new User("a"));
lists.add(new User("b"));
lists.add(new User("c"));
List<User> collect = lists.stream().peek(p -> {
p.setName("1"+p.getName());
}).collect(Collectors.toList());
}
@Data
public static class User {
private String name;
public User(String name) {
this.name = name;
}
}
}
sonarlint中的描述謹慎使用peek().png
根據(jù)其 JavaDocs,中間 Stream 操作 java.util.Stream.peek() “存在主要是為了支持調(diào)試”目的牍颈。
與其他中間 Stream 操作的一個主要區(qū)別是 Stream 實現(xiàn)可以自由地跳過對 peek() 的調(diào)用以進行優(yōu)化言疗。 這可能導(dǎo)致 peek() 僅針對 Stream 中的某些元素或沒有元素被意外調(diào)用。
因此颂砸,在沒有仔細考慮的情況下依賴 peek() 會導(dǎo)致代碼容易出錯。
此規(guī)則為 peek() 的每次使用提出了一個問題死姚,以確保團隊對其進行挑戰(zhàn)和驗證以用于生產(chǎn)調(diào)試/日志記錄目的人乓。
3. 完全可以使用map或者forEach進行取代
上面的場景,使用forEach進行取代:
lists.forEach(p->p.setName("1"+p.getName()));
所以都毒,還是謹慎使用peek()函數(shù)來進行操作吧I!!