JB Header
Java 8 - How to 'peek' into a running Stream| Stream.peek method tutorial with examples
Overview This tutorial looks at Java 8 Stream API's peek() method in depth. It starts with explaining the Stream.peek() method's definition and intended use.This is followed by understanding the method's intermediate and non-interfering nature. Lastly, we will look at the Java 8 code showing a working example of Stream.peek() and its explanation. Java 8's Stream.peek() method Let us start with looking at the signature of Stream.peak() method -
Stream<T> peek(Consumer<? super T> action);
Where,
     - action is the only parameter and is an instance of a Consumer Functional InterfaceClick to read detailed tutorial on Consumer Functional Interfaces
     - The method returns back a Stream<T> as output which consists of the same elements as in Stream<T> instance it had been invoked on, after applying the consuming action, passed as input, on each of them.

The Stream.peek() method's objective is literally to peek at the contents of the Stream. I.e. it has been put as a part of Streams API to provide a method for debugging the Stream elements as they flow from one pipelined operationClick to read tutorial on Pipelines in Computing to another. The stream.peek() method applies the Consumer<T> function's logic, which is its only input, to each element of the Stream. The Consumer logic can be implemented as per the specific debugging requirements requirements to debug/log/print the elements as they stream through the peek() method.
But then, one might ask the question, how is Stream.peek() method different from any other method of the Stream API which can consume the values in the Stream? The answer is that this is the only method which allows you to consume(print/log/whatever way you want to check the contents) the elements of a Stream as an intermediate operationClick to Read Tutorial explaining intermediate & terminal Stream operations. In addition, Stream.peek() also provides the guarantee of non-interference. Let us now look at what we mean by peek() method having these two advantages.

Stream.peek() as a non-interfering intermediate operation Stream.peek() is an intermediate operation, i.e. it does not end the processing of the stream. Other methods which allow using a Consumer instance to act on the elements of a stream, such as the forEach() methodRead tutorial on forEach() method, or the collect() method among others, are all terminal operationsClick to Read Tutorial explaining intermediate & terminal Stream operations. I.e. once you see the contents, by printing or logging them, your stream's processing ends. Stream.peek() thus provides you the unique capability to consume a stream without ending the pipeline of operations when acting on the stream contents, by virtue of it being an intermediate operation.

In addition, Stream.peek() is a non-interfering Stream operation. Non-interfering methods are those which guarantee that they will not modify the Stream’s data source during their execution. Non-interfering nature is required in multi-threaded environments where stream operations can be executed in parallel or concurrently. Concurrent execution makes it necessary to keep the stream's data source unmodified until the terminal operation.

Let us now take a look at an example showing Stream.peek() method's usage -
Java 8 code showing Stream.peek() method's usage
package com.javabrahman.java8.streams;
import java.util.stream.Stream;
public class PeekingInStreams {
  public static void main(String args[]) {
    Stream.iterate(1, (Integer n) -> n + 1)
      .peek(n -> System.out.println("number generated: - " + n))
      .filter(n -> (n % 2 == 0))
      .peek(n -> System.out.println("Even number filter passed for - " + n))
      .limit(5)
      .count();
  }
}
 OUTPUT of the above code
number generated - 1
number generated - 2
Even number filter passed for - 2
number generated - 3
number generated - 4
Even number filter passed for - 4
number generated - 5
number generated - 6
Even number filter passed for - 6
number generated - 7
number generated - 8
Even number filter passed for - 8
number generated - 9
number generated - 10
Even number filter passed for - 10
Explanation of the code Conclusion In the above Java 8 Stream.peek() method tutorial we understood the working of the method by going through its definition, charecteristics and usage. Lastly, we saw a Java 8 code example showing Stream.peek() method's usage practically.