1. Introduction
I described the difference between map and flatMap operations in the Java8 Stream API in Map and flatMap. Then a friend told me that the peek operation can also achieve element processing. But do you know the difference between Map and Peek? Map was covered at the beginning of this article, so you can look at it in more detail. This article focuses on the Peek operation.
2. peek
The peek operation receives a Consumer
function. As the name implies, the peek operation consumes each element in the flow using the logic provided by the Consumer
function, possibly changing some attributes inside the element. Here we will mention the word Consumer
to understand what consumption is.
2.1 What is Consumer?
package java.util.function;
import java.util.Objects;
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
Accept (accept); after. Accpet (accept
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return(T t) -> { accept(t); after.accept(t); }; }}Copy the code
Consumer
is a functional interface. An abstract method void Accept (T T) means to take a parameter of type T and consume it. In fact, consumption gives me the feeling of “use up”, and the natural return is void. There are usually two ways to “use up” T:
- Void method of T itselfThe typical one is
setter
。 - Pass T to the void method of another interface (class) for processingFor example, we often print an object
System.out.println(T)
2.2 Peek Operation demonstration
Stream<String> stream = Stream.of("hello"."felord.cn");
stream.peek(System.out::println);
Copy the code
If you test the code shown above you will find that it does not run logically at all. Why? This is because the life cycle of a flow has three phases:
- Initial generation phase.
- Intermediate operations fetch and process elements one by one. Dispensable. All intermediate operations are inert, so no action has any effect until the flow flows through the pipe.
- Terminal operation. Usually divided intoFinal consumption (
foreach
And so on) andinductive (collect
Two classes). It is also important that terminal operations initiate the flow through the pipe.
So it should be the following:
Stream<String> stream = Stream.of("hello"."felord.cn");
List<String> strs= stream.peek(System.out::println).collect(Collectors.toLIst());
Copy the code
For example, in the image below, we add a box to the sphere:
3. peek VS map
The PEEK operation is generally used when you do not want to change the type of the element itself in the stream or when you want to manipulate the internal state of the element. A map, on the other hand, is used to change the type of the element itself in the stream, that is, to derive another type from the element. That’s the big difference between them. So what scenarios do we use Peek in practice? For example, peek is appropriate for batching certain properties of T in Stream
. Map is best if we want to get a collection of properties of T from Stream
.
4. To summarize
Today we looked at the Stream peek operation and reviewed the Stream life cycle. The Consumer
function is also explained in passing. It also compares map with map and explains the usage scenarios of each. I’m sure you’ll understand them better after reading this article.
Follow our public id: Felordcn for more information
Personal blog: https://felord.cn