Peek является промежуточной операцией и существует главным образом для поддержки отладки, когда вы хотите видеть элементы, проходящие мимо определенной точки в конвейере.
Пример того, как peek может использоваться в вашем коде :
List<String> alphabets = Arrays.asList(new String[]{"a","b","c"});
List<String> upper = alphabets.stream()
.peek(l -> System.out.println("Filtered value: " + l))
.map(l -> l.toUpperCase())
.peek(l -> System.out.println("Mapped value: " + l))
.collect(Collectors.toList());
upper.forEach(System.out::println);
Это выводит:
Filtered value: a
Mapped value: A
Filtered value: b
Mapped value: B
Filtered value: c
Mapped value: C
A
B
C
В то время как результаты карты представляют собой поток результатов, применяющих данную функцию в пике, это просто исходный поток результатов. А поскольку строки в java являются неизменяемыми, выполнение функции не будет зависеть от выполнения функции.
Если бы элементы были ссылками (как объекты), а функция peek обновила содержимое этих ссылок, они бы были обновлены, но это не тот случай.
Пример просмотра с объектом MyString:
class MyString {
String str;
MyString(String str) {
this.str = str;
}
public void toUpperCase() {
str = str.toUpperCase();
}
@Override
public String toString() {
super.toString();
return str;
}
}
List<MyString> alphabets = Arrays.asList(new MyString[]{new MyString("a"), new MyString("b"), new MyString("c")});
List<MyString> upper = alphabets.stream()
.peek(l -> l.toUpperCase())
.collect(Collectors.toList());
upper.forEach(System.out::println);
полный код см. здесь:
http://tpcg.io/6GlwFizW
Вы можете видеть, что на выходе получается:
A
B
C
, так как в этом случае мы изменяем внутреннее состояние каждого элемента.
Обратите внимание, что я специально сделал, чтобы MyString.toUpperCase () возвратил void вместо объекта MyString, поэтому он не сможет работать с map таким образом.