Use of operation type and peek in Java 8 stream

Use of operation type and peek in Java 8 stream

brief introduction

As a stream operation, Java 8 stream has two types of operations: intermediate operation and termination operation. 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);

In the above example, our intention is to print out the value of stream, but there is actually no output.

Why?

Intermediate operation and termination operation

A Java 8 stream consists of three parts. Data source, zero or one or more intermediate operations, one or zero termination operations.

Intermediate operations are data processing. Note that intermediate operations are lazy operations and will not be started immediately. They will not be executed until the operation is terminated.

The termination operation is the start operation of the stream. Only when the termination operation is added can the stream really start to execute.

Therefore, the problem is solved. Peek is an intermediate operation, so the above example has no output.

peek

Let's take a look at peek's documentation: PEEK is mainly used for debugging.

Let's look at the use of debug:

Stream.of("one","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());

The above example output:

Filtered value: three
Mapped value: THREE
Filtered value: four
Mapped value: FOUR

In the above example, we output the intermediate value of stream to facilitate our debugging.

Why is it only used as debug? Let's take another example:

Stream.of("one","four").peek(u -> u.toUpperCase())
                .forEach(System.out::println);

In the above example, we use peek to convert element into upper case. Then output:

one
two
three
four

You can see that the elements in the stream are not converted to uppercase format.

Let's take another look at the map comparison:

Stream.of("one","four").map(u -> u.toUpperCase())
                .forEach(System.out::println);

Output:

ONE
TWO
THREE
FOUR

You can see that the map actually transforms the elements.

Of course, peek has exceptions. What if there is an object in our stream?

    @Data
    @AllArgsConstructor
    static class User{
        private String name;
    }
        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);

Output results:

10:25:59.784 [main] INFO com.flydean.PeekUsage - [PeekUsage.User(name=kkk),PeekUsage.User(name=kkk),PeekUsage.User(name=kkk)]

We see that if it is an object, the actual result will be changed.

Why is peek different from 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);

Peek receives a consumer and map receives a function.

The consumer does not return a value. It only performs some operations on the elements in the stream, but the data after the operation is not returned to the stream, so the elements in the stream are still the original elements.

Function has a return value, which means that all operations on stream elements will be returned to stream as new results.

This is why peek string will not change, but peek object will send changes.

conclusion

In this article, we explained the two operation types of stream and summarized the use of peek. I hope you can master it.

Examples of this article https://github.com/ddean2009/learn-java-streams/tree/master/stream-peek

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>