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
Where,
-
- The method returns back a
The
But then, one might ask the question, how is
In addition,
Let us now take a look at an example showing Stream.peek() method's usage -
OUTPUT of the above code
Explanation of the code
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);
-
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.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();
}
}
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
PeekingInStreams
class first creates an infinite stream using Stream.iterate()Click to read tutorial on Creating Infinite Streams using iterate() method method by specifying logic to generate consecutive integers starting from 1.- Next
iterate()
method is pipelined to thepeek()
method which uses a lambda expressionRead Java 8 Lambda Expressions Tutorial equivalent of the Consumer interface -(n -> System.out.println("number generated: - " + n))
. This expressions simply prints the generated number. - Next, a filter is applied to the Stream using the Stream.filter()Click to read how Filtering and Slicing with Java 8 Streams works method. The filter's predicateClick to read tutorial on Java 8 Predicates only allows even numbers to pass through using the logic
n%2==0
. peek()
is again pipelined next, and it prints the numbers obtained from the filter indicating which numbers passed the even number filter.Stream.limit()
method is used to restrict the infinite stream to5
numbers.- Lastly, to end the pipeline of operations,
Stream.count()
method is invoked which is a terminal operation. - As expected, the output shows that only even numbers - 2,4,6,8,10 pass through the filter.
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.Java 8 Streams API tutorials on JavaBrahman
Streams API - Introduction & BasicsClick to Read tutorial on Streams API Basics Understanding Stream Operations | Intermediate and Terminal OperationsClick to Read Tutorial on Stream Operations Overview Mapping with Streams using map and flatMap methodsClick to Read how Mapping with Java8 Streams works Filtering and Slicing with Streams using filter,distinct,limit,skip methodsClick to Read how Filtering and Slicing with Java8 Streams works Matching with Streams using allMatch,anyMatch,noneMatch methodsClick to Read tutorial on matching with Streams API Stream API's findFirst,findAny methods' tutorialClick to Read tutorial on findFirst() and findAny() methods of Streams API 'Peeking' into a running Stream with Stream.peek() methodClick to Read tutorial on Stream.peek() method Creating Infinite Streams with iterate\generate methodsClick to Read tutorial on Creating Infinite Streams Reducing Streams using Streams.reduce methodClick to Read tutorial on Reducing Streams
Streams API - Introduction & BasicsClick to Read tutorial on Streams API Basics Understanding Stream Operations | Intermediate and Terminal OperationsClick to Read Tutorial on Stream Operations Overview Mapping with Streams using map and flatMap methodsClick to Read how Mapping with Java8 Streams works Filtering and Slicing with Streams using filter,distinct,limit,skip methodsClick to Read how Filtering and Slicing with Java8 Streams works Matching with Streams using allMatch,anyMatch,noneMatch methodsClick to Read tutorial on matching with Streams API Stream API's findFirst,findAny methods' tutorialClick to Read tutorial on findFirst() and findAny() methods of Streams API 'Peeking' into a running Stream with Stream.peek() methodClick to Read tutorial on Stream.peek() method Creating Infinite Streams with iterate\generate methodsClick to Read tutorial on Creating Infinite Streams Reducing Streams using Streams.reduce methodClick to Read tutorial on Reducing Streams