Operation types and use of peek in Java 8 Stream
Introduction to the
Java 8 Stream as a stream operation has two types of operations, intermediate operations and termination operations. What’s the difference between the two?
Let’s look at an example of peek:
Stream<String> stream = Stream.of("one"."two"."three"."four");
stream.peek(System.out::println);
Copy the code
In the example above, we intended to print the value of Stream, but we didn’t actually print anything.
Why is that?
Intermediate operations and termination operations
A Java 8 Stream consists of three parts. Data source, zero or one or more intermediate operations, one or zero termination operations.
An intermediate operation is a process of data. Note that an intermediate operation is lazy and does not start immediately.
The termination operation is the start operation of the stream, and the stream will not actually start executing until the termination operation is added.
So, problem solved, peek is an intermediate operation, so the above example has no output.
peek
Peek is mainly used for debugging purposes.
Let’s look at the debug usage:
Stream.of("one"."two"."three"."four").filter(e -> e.length() > 3)
.peek(e -> System.out.println("Filtered value: " + e))
.map(String::toUpperCase)
.peek(e -> System.out.println("Mapped value: " + e))
.collect(Collectors.toList());
Copy the code
The above example output:
Filtered value: three
Mapped value: THREE
Filtered value: four
Mapped value: FOUR
Copy the code
In the above example we printed the intermediate value of stream to facilitate our debugging.
Why only debug? Let’s look at another example:
Stream.of("one"."two"."three"."four").peek(u -> u.toUpperCase())
.forEach(System.out::println);
Copy the code
In the example above we used peek to convert Element to upper Case. Then output:
one
two
three
four
Copy the code
You can see that the elements in the stream are not converted to uppercase.
Here’s another map comparison:
Stream.of("one"."two"."three"."four").map(u -> u.toUpperCase())
.forEach(System.out::println);
Copy the code
Output:
ONE
TWO
THREE
FOUR
Copy the code
You can see that the map actually transforms the elements.
There are exceptions for peek, of course. What if we had an object in the Stream?
@Data
@AllArgsConstructor
static class User{
private String name;
}
Copy the code
List<User> userList=Stream.of(new User("a"),new User("b"),new User("c")).peek(u->u.setName("kkk")).collect(Collectors.toList());
log.info("{}",userList);
Copy the code
Output result:
10:25:59.784 [main] infocom.flydean.peekUsage - [peekusage. User(name= KKK), peekusage. User(name= KKK), PeekUsage.User(name=kkk)]Copy the code
We see that the actual result is changed for objects.
Why the difference between Peek and Map?
Let’s look at the definitions of PEEK and Map:
Stream<T> peek(Consumer<? super T> action)
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
Copy the code
Peek receives a Consumer, and Map receives a Function.
Consumer does not return a value. It does something to the elements in the Stream, but the data is not returned to the Stream, so the elements in the Stream remain the same.
Function, on the other hand, returns a value, which means that all operations on elements of the Stream are returned to the Stream as new results.
This is why peek String does not change while Peek Object sends changes.
conclusion
In this article, we looked at the two types of operations on STREAM and summarized the use of PEEK. I hope you get the hang of it.
Examples of this article github.com/ddean2009/l…
Welcome to pay attention to my public number: procedures those things, more wonderful waiting for you! For more, visit www.flydean.com