Java Streams for Programmers
Java Streams for Programmers
Collection Streams
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020
Pearson Education, Inc. All rights reserved.
1
Motivations
Double[] numbers = {2.4, 55.6, 90.12, 26.6};
Set<Double> set = new HashSet<>(Arrays.asList(numbers));
int count = 0;
for (double e: set)
if (e > 60) count++;
System.out.println("Count is " + count);
The code is fine. However, Java provides a better and simpler way
for accomplishing the task. Using the aggregate operations, you can
rewrite the code as follows:
System.out.println("Count is " +
set.stream().filter(e -> e > 60).count());
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020
Pearson Education, Inc. All rights reserved.
2
Stream
A collection stream or simply stream is a sequence of elements. The
filter and count are the operations that you can apply on a stream.
These operations are known as aggregate operations, because they
are applied to a collection of data.
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020
Pearson Education, Inc. All rights reserved.
3
Objectives
To use aggregate operations on collection streams to simplify coding and improve
performance (§30.1).
To create a stream pipeline, apply lazy intermediate methods (skip, limit, filter,
distinct, sorted, map, and mapToInt), and terminal methods (count, sum, average,
max, min, forEach, findFirst, firstAny, anyMatch, allMatch, noneMatch, and
toArray) on a steam (§30.2).
To process primitive data values using the IntStream, LongStream, and DoubleStream
(§30.3).
To create parallel streams for fast execution (§30.4).
To reduce the elements in a stream into a single result using the reduce method (§30.5).
To place the elements in a stream into a mutable collection using the collect method
(§30.6).
To group the elements in a stream and apply aggreate methods for the elements in the
groups (§30.7).
To use a variety of examples to demonstrate how to simplify coding using streams
(§30.8 ).
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020
Pearson Education, Inc. All rights reserved.
4
«interface»
java.util.stream.BaseStream<T, S extends<BaseStream<T, S>>
Stream Class
+close(): S Closes this stream.
+parallel(): S Returns an equivalent stream that is executed in parallel.
+sequential(): S Returns an equivalent stream that is executed in sequential.
+isParallel(): boolean Returns true if this stream is parallel.
«interface»
java.util.stream.Stream<T>
+distinct(): Stream<T> Returns a stream consisting of distinct elements from this stream.
+filter(p: Predicate<? super T): Stream<T> Returns a stream consisting of the elements matching the predicate.
+limit(n: long): Stream<T> Returns a stream consisting of the first n elements from this stream.
An intermediate +skip(n: long): Stream<T> Returns a stream consisting of the remaining elements in this stream after
discarding the first n elements.
+sorted(): Stream<T>
method transfroms
Returns a stream consisting of the elements of this stream sorted in a
natural order.
Intermediate +sorted(comparator: Comparator<? super T>): Returns a stream consisting of the elements of this stream sorted using the
Stream<T> comparator.
a stream into
operations
+map(mapper: Function<? super T, ? extends Returns a stream consisting of the results of applying the function to the
R>: Stream<R> elements of this stream.
another stream.
+mapToInt(mapper: ToIntFunction<? super Returns an IntStream consisting of the results of applying the function
T>): IntStream to the elements of this stream.
+mapToLong(mapper: ToLongFunction<? super Returns a LongStream consisting of the results of applying the function
T>): LongStream to the elements of this stream.
+mapToDouble(mapper: ToDoubleFunction<? Returns a DoubleStream consisting of the results of applying the
super T>): DoubleStream function to the elements of this stream.
An terminal
+count(): long Returns the number of elements in this stream.
+max(c: Comparator<? super T>): Optional<T> Returns the maximum element in this stream based on the comparator.
+min(c: Comparator<? super T>): Optional<T> Returns the minimum element in this stream based on the comparator.
terminates a
operations +forEach(action: Consumer<? super T>): void Performs an action for each element of this stream.
+reduce(accumulator: BinaryOperator<T>): T Reduces the elements in the stream to a value using the identity and an
associative accumulation function. Return an Optional describing the
stream.
reduced value.
+reduce(identity: T, accumulator: Reduces the elements in the stream to a value using the identity and an
BinaryOperator<T>): T associative accumulation function. Return the reduced value.
+collect(collector: <? super <T, A, R>>): R Performs a mutable reduction operation on the elements of this stream
using a Collector.
set.stream().limit(50).distict().count()
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020
Pearson Education, Inc. All rights reserved.
6
Functional Interface Arguments
Most of the arguments for stream methods are instances of
functional interfaces. So the arguments can be created using lambda
expressions or method references.
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020
Pearson Education, Inc. All rights reserved.
7
forEach Method
forEach(e -> System.out.print(e + " ")) forEach(
new java.util.function.Consumer<String>() {
public void accept(String e) {
System.out.print(e + " ");
}
}
)
The lambda expression not only simplifies the code, but also the
concept of the method. You can now simply say that for each
element in the stream perform the action as specified in the
expression.
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020
Pearson Education, Inc. All rights reserved.
8
The sorted Method
sorted() is to sort the elements in their natural order and
sorted(Comparator) sorts using the specified comparator.
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020
Pearson Education, Inc. All rights reserved.
9
The filter Method
The filter method takes an argument of the Predicate<? super T>
type, which is a functional interface with an abstract method test(T
t) that returns a Boolean value. The method selects the elements
from the stream that satisfies the predicate.
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020
Pearson Education, Inc. All rights reserved.
10
The max and min Methods
The max and min methods take an argument of the Comparator<?
Super T> type. This argument specifies how the elements are
compared in order to obtain the maximum and minimum element.
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020
Pearson Education, Inc. All rights reserved.
11
The anyMatch, allMatch, and
noneMatch Methods
The anyMatch, allMatch, and noneMatch methods take an
argument of the Predicate<? super T> type to test if the stream
contains an element, all elements, or no element that satisfies the
predicate.
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020
Pearson Education, Inc. All rights reserved.
12
The map Method
The map method returns a new stream by mapping each element in
the stream into a new element. The map method takes an argument
of the Function<? super T, ? super R> type to return an instance
of the Stream<R>. The Function is a functional interface with an
abstract method apply(T t) that maps t into a value of the type R.
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020
Pearson Education, Inc. All rights reserved.
13
IntStream, LongStream, and
DoubleStream
Stream represents a sequence of objects. In addition to Stream, Java
provides IntStream, LongStream, and DoubleStream for
representing a sequence of int, long, and double values. These streams
are also subinterfaces of BaseStream. You can use these streams in the
same way like a Stream. Additionally, you can use the sum(),
average(), and summaryStatistics()methods for returning the sum,
average, various statistics of the elements in the stream. You can use
the mapToInt method to convert a Stream to an IntStream and use
the map method to convert any stream including an IntStream to a
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020
Stream. Pearson Education, Inc. All rights reserved.
14
IntStream, LongStream, and
DoubleStream Examples
IntStreamDemo
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020
Pearson Education, Inc. All rights reserved.
15
Parallel Streams
Streams can be executed in parallel mode to improve performance.
The stream() method in the Collection interface returns a sequential
stream. To execute operations in parallel, use the parallelStream()
method in the Collection interface to obtain a parallel stream. Any
stream can be turned to into a parallel stream by invoking the
parallel() method defined in tbe BaseStream interface. Likewise,
you can turn a parallel stream into a sequential stream by invoking
the sequential() method.
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020
Pearson Education, Inc. All rights reserved.
16
Parallel Streams
Streams can be executed in parallel mode to improve performance.
The stream() method in the Collection interface returns a sequential
stream. To execute operations in parallel, use the parallelStream()
method in the Collection interface to obtain a parallel stream. Any
stream can be turned to into a parallel stream by invoking the
parallel() method defined in tbe BaseStream interface. Likewise,
you can turn a parallel stream into a sequential stream by invoking
the sequential() method.
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020
Pearson Education, Inc. All rights reserved.
17
Parallel Streams Example
ParallelStreamDemo
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020
Pearson Education, Inc. All rights reserved.
18
Stream Reduction Using the
reduce Method
int total = 0; int sum = s.parallelStream()
for (int e: s) { .reduce(0, (e1, e2) -> e1 + e2);
total += e;
}
The reduce method makes the code
concise. Moreover, the code is
parallelizable, because multiple processors
can simultaneously invoke the
applyAsInt method on two integers
repeatedly.
StreamReductionDemo
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020
Pearson Education, Inc. All rights reserved.
19
Stream Reduction Using the
collect Method
You can use the collect method to reduce the elements in a stream
into a mutable container.
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020
Pearson Education, Inc. All rights reserved.
20
Stream Reduction Using the
collect Method
<R> R collect(Supplier<R> supplier, CollectDemo
BiConsumer<R, ? super T> accumulator,
BiConsumer<R, R> combiner)
For example
String[] names = {"John", "Peter", "Susan", "Kim",
"Jen", "George", "Alan", "Stacy", "Michelle", "john"};
StringBuilder sb = Stream.of(names).collect(() -> new
StringBuilder(),
(c, e) -> c.append(e), (c1, c2) -> c1.append(c2));
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020
Pearson Education, Inc. All rights reserved.
21
Stream Reduction Using the
collect Method
CollectDemo
StringBuilder sb =
Stream.of(names).collect(StringBuilder::new,
StringBuilder::append, StringBuilder::append);
ArrayList<String> list =
Stream.of(names).collect(ArrayList::new,
ArrayList::add, ArrayList::addAll);
ArrayList<String> list =
Stream.of(names).collect(Collectors.toList());
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020
Pearson Education, Inc. All rights reserved.
22
Grouping Elements Using the
groupingBy Collector
You can use the groupingBy collector along with the collect
method to collect the elements by groups.
CollectGroupDemo
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020
Pearson Education, Inc. All rights reserved.
23
Case Studies: Analyzing Numbers
AnalyzeNumbersUsingStream
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020
Pearson Education, Inc. All rights reserved.
24
Case Studies: Counting the
Occurrences of Each Letter
CountLettersUsingStream
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020
Pearson Education, Inc. All rights reserved.
25
Case Studies: Counting the
Occurrences of Each Letter in a
String
CountOccurrenceOfLettersInAString
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020
Pearson Education, Inc. All rights reserved.
26
Case Studies: Processing All
Elements in a Two-Dimensional
Array
TwoDimensionalArrayStream
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020
Pearson Education, Inc. All rights reserved.
27
Case Studies: Finding the Directory
Size
DirectorySizeStream
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020
Pearson Education, Inc. All rights reserved.
28
Case Studies: Counting Keywords
CountKeywordStream
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020
Pearson Education, Inc. All rights reserved.
29
Case Studies: Occurrences of Words
CountOccurrenceOfWordsStream
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020
Pearson Education, Inc. All rights reserved.
30