Java 8 Stream API Explained
Java 8 Stream API Explained
com/java-8-stream-api/
In this article, we’ll learn everything regarding Java Stream API that was introduced
in Java 8, through detailed examples.
1 of 33 29/03/23, 8:13 pm
Java 8 Stream API - You Learn Code [Link]
JAVA
Table ofSPRING
ContentsBOOT
2 of 33 29/03/23, 8:13 pm
Java 8 Stream API - You Learn Code [Link]
JAVA SPRING
4.5 Stream BOOT
min(Comparator
comparator) and max(Comparator comparator)
Example
4.6 Stream count Example
4.7 Stream anyMatch(Predicate), allMatch(Predicate) and
noneMatch(Predicate) Examples
4.8 Stream findFirst() and findAny() Examples
4.9 Stream collect Methods
4.9.1 Stream R collect(Supplier supplier, BiConsumer accumulator, BiConsumer
combiner) Example
4.9.2 Stream R collect(Collector collector) Examples
[Link] [Link]() Example
[Link] [Link]() Example
[Link] [Link]() Example
[Link] [Link]() Example
[Link] [Link]() Example
[Link] [Link]() Example
[Link] [Link]() Example
[Link] [Link]() Example
5. A Visualization of Java 8 Stream
6. Conclusion
7. Sources
3 of 33 29/03/23, 8:13 pm
Java 8 Stream API - You Learn Code [Link]
2. Terminal Operations:
BOOT These operations will transform the stream into another
JAVA SPRING
primitive or object. After applying a terminal operation, you could have an int ,
long , String, Optional, any collection(such as List, Set), or even a Map.
An important characteristic of a stream is that once you have performed any of the
intermediate or terminal operations, you will be unable to perform more operations
unless you chain them. Consider the example below:
stream
.map(String::toLowerCase)
.forEach([Link]::println);
Before we delve into streams, I suggest that you read the following articles as they
would help a lot in taking full advantage of the stream API.
4 of 33 29/03/23, 8:13 pm
Java 8 Stream API - You Learn Code [Link]
null
JAVA value, use [Link](T
you can BOOT
SPRING
t) .
2.2 [Link]()
This method follows the builder pattern and it is a different way to create and fill a
stream. One difference with the previous way of creating a stream is that by using
builder, you are obliged to declare your stream as Stream<Object>.
As you can observe, this stream now has one element; a list that has two strings. If
you want to convert it to a Stream<String> you would need to use flatMap()
which will see later how it works.
Finally, If you need an empty stream, you can use the [Link]() method.
5 of 33 29/03/23, 8:13 pm
Java 8 Stream API - You Learn Code [Link]
In the above examples, we used the stream() method the Collection interface has,
then filtered all the values that are equal to “C” and converted them back to the
original data structure.
So if you would like to create a stream and, print the all powers of two, from 20 to 219,
you could do it as shown below:
Stream
.iterate(1, i -> i * 2)
.limit(20).
forEach([Link]::println);
Stream
.iterate([Link](0, 1), fibList ->
[Link]([Link](1), [Link](0) +
[Link](1)
))
.limit(10)
.map(list -> [Link](0))
6 of 33 29/03/23, 8:13 pm
Java 8 Stream API - You Learn Code [Link]
.forEach([Link]::println);
JAVA SPRING BOOT
Stream
.iterate(1, i -> i < 10, i -> i + 1)
.limit(20)
.forEach([Link]::println);
Stream
.concat(clh, programmingLanguages)
.forEach([Link]::println);
In order to make our examples more interesting, consider that we have created the
following setup:
7 of 33 29/03/23, 8:13 pm
Java 8 Stream API - You Learn Code [Link]
The filter() method allows you to filter only the elements of the stream that match
this predicate.
Below you can find an example where we filter only the cars that cost more than
$30,000.
cars
.stream()
.filter(car -> [Link]() > 30_000)
.forEach([Link]::println);
After we filter, we print every element that currently exists in the stream using
forEach(Consumer consumer) . The output is the following:
If you want to learn more about how filter() works, check this article.
The map() method allows you to transform all the elements of the stream to any
type that you might need.
Below you can find an example where we convert the car objects to simple strings
that contain the model of each car.
8 of 33 29/03/23, 8:13 pm
Java 8 Stream API - You Learn Code [Link]
cars
[Link]()
SPRING BOOT
.map(Car::model)
.forEach([Link]::println);
Gallardo
C180
Insignia
Polo
M3
If you want to learn more about how map() works, check this article.
cars
.stream()
.mapToInt(Car::horsePower).average();
cars
9 of 33 29/03/23, 8:13 pm
Java 8 Stream API - You Learn Code [Link]
.stream()
[Link](Car::price).sum();
SPRING BOOT
As you can observe, each list has some brands, let’s say we have a task to convert
this to a simple List<String> . How would we do that? Here comes flatMap into
play:
As a result, our list will now contain just strings and not a list of strings.
10 of 33 29/03/23, 8:13 pm
Java 8 Stream API - You Learn Code [Link]
[Link](
JAVA SPRING BOOT
[Link](
new Car(8L, "Opel", "Corsa", 80, 18_000))
);
Now let’s say that your task is to find the max price of all cars inside the
carsDeepList , you can do it as shown below:
[Link](brandsFlat);
▪ When we like to replace each element of the stream with a very small number of
elements, since we would avoid creating a new stream like flatMap() does.
Consider an example that falls to the first reason why we might opt for mapMulti
instead of flatMap .
[Link]().<Map<String, String>>mapMulti(
((carsList, consumer) -> {
for(Car car: carsList){
if([Link]() < 0.05){
11 of 33 29/03/23, 8:13 pm
Java 8 Stream API - You Learn Code [Link]
[Link](
JAVA SPRING BOOT [Link]([Link](), [Link]())
);
}
}
}
));
This will convert a list of lists of cars to a list of maps with the model as a key and the
brand as value, with a 5% probability.
As you would expect, the result would be to print 4 cars in total instead of 5. Note that
the 5th element has a different id so it is considered a different object. Hence,
equals() would return false when compared to any other element.
12 of 33 29/03/23, 8:13 pm
Java 8 Stream API - You Learn Code [Link]
.sorted().forEach([Link]::println);
JAVA SPRING BOOT
//Will print them in ascending lexicographical order
[Link]("Code", "Learn", "Hub", "Hello", "World")
.sorted().forEach([Link]::println);
//Will fail as Car object does not implement comparable interface
try {
[Link](new Car(1, "Opel", "Astra", 105, 20_000),
new Car(2, "Lamborghini", "Gallardo", 320,
120_000),
new Car(3, "Mercedes", "C180", 200, 40_000))
.sorted()
.forEach([Link]::println);
} catch (Exception e){
[Link]();
}
-1
0
1
3
5
100
Code
Hello
Hub
Learn
World
[Link]: class StreamExamples$Car cannot be cast
to class [Link] (StreamExamples$Car is in unnamed module
of loader 'app'; [Link] is in module [Link] of loader
'bootstrap')
Now, if for example, you wanted to sort the cars by ascending price, you could
change the record as follows:
13 of 33 29/03/23, 8:13 pm
Java 8 Stream API - You Learn Code [Link]
return 0;
JAVA SPRING
} else BOOT
{
return -1;
}
}
};
Let’s say you’d like cars to be sorted in descending order by the following criteria:
1. price
2. horsePower
3. brand
14 of 33 29/03/23, 8:13 pm
Java 8 Stream API - You Learn Code [Link]
Note that since stream operations are lazy, they won’t be run until you collect the
result.
15 of 33 29/03/23, 8:13 pm
Java 8 Stream API - You Learn Code [Link]
.toList();
JAVA SPRING BOOT
This will print only the first two elements as the other 3 will be truncated from the
stream.
16 of 33 29/03/23, 8:13 pm
Java 8 Stream API - You Learn Code [Link]
For ordered streams, it just filters the elements while the predicate returns
true . If at some point the predicate returns false for an element, this and the
rest of the elements will be filtered out. Let’s jump to an example:
So here, the Opel Astra will fail the predicate, and even though the rest of the cars do
have price >= $40,000 , the output will be just Car[id=1, brand=Lamborghini,
model=Gallardo, horsePower=320, price=120000.0]
17 of 33 29/03/23, 8:13 pm
Java 8 Stream API - You Learn Code [Link]
In the following sections, we’ll see all terminal operations provided by stream API.
18 of 33 29/03/23, 8:13 pm
Java 8 Stream API - You Learn Code [Link]
C
JAVA SPRING BOOT in parallel
Using forEachOrdered stream:
C
L
H
Moreover, you can perform actions inside forEach , consider a simple Car POJO like
the record we had in the previous sections, and let’s say we would like to increase
the prices of some cars due to inflation:
carPojoList
.stream()
.forEach(carPojo -> {
switch ([Link]()){
case "Opel" -> [Link]([Link]() *
1.1);
case "Mercedes", "BMW" ->
[Link]([Link]() * 1.2);
case "Lamborghini" ->
[Link]([Link]() * 1.4);
}
});
[Link]([Link]::println);
After these operations, the result to be printed will have the updated prices:
19 of 33 29/03/23, 8:13 pm
Java 8 Stream API - You Learn Code [Link]
generator)
JAVA SPRINGExamples
BOOT
You can use these two methods to convert a stream to an array. Note that the first
one will return an array of type Object while the second one whatever type you
might specify.
The first version just uses a BinaryOperator to combine the values and produce a
result. Note that this version returns an Optional.
The second version works like the first, but it uses a value to start with instead of the
20 of 33 29/03/23, 8:13 pm
Java 8 Stream API - You Learn Code [Link]
default
JAVA (e.g. for double the default would be 0.0.).
SPRING BOOT
The third version allows you to change the produced result by using a BiFunction
and a BinaryOperator .
However, if we dig deeper and use a debugger, we’ll see that the List produced by
Collectors class will be shown as ArrayList while the List produced by
toList() will be shown as [Link] which is unmodifiable.
Let’s see an example where we find the cheapest and the most expensive car:
21 of 33 29/03/23, 8:13 pm
Java 8 Stream API - You Learn Code [Link]
Car expensive =
[Link]().max([Link](Car::price)).orElse(null);
Car cheap =
[Link]().min([Link](Car::price)).orElse(null);
[Link]("Most expensive car is: "+expensive);
[Link]("Cheapest car is: "+cheap);
▪ anyMatch() will return true if at least one element matches the predicate.
22 of 33 29/03/23, 8:13 pm
Java 8 Stream API - You Learn Code [Link]
▪ allMSPRING
JAVA atch() will
BOOTreturn tru
e if all elements match the predicate.
▪ noneMatch() will return true if none of the elements match the predicate.
▪ findAny() is non-deterministic (it won’t produce the same result each time
is run) and it is mainly used to maximize performance in parallel
operations.
Finally, you can notice the difference when using parallel streams as shown below:
23 of 33 29/03/23, 8:13 pm
Java 8 Stream API - You Learn Code [Link]
.parallel()
JAVA SPRING BOOT
.findFirst()
.orElse(null);
[Link](any);
[Link](first);
▪ A Supplier , which is used to choose the object or the data structure that our
stream will be converted to.
▪ A BiConsumer , which is the accumulator i.e. the operation that will be applied in
order to fill the object or data structure (the first parameter will be the DS and the
second the element to be added).
▪ A BiConsumer , which is the combiner i.e. the operation that we will use to
combine all the values produced by the accumulator.
Consider the example below where we convert a stream of cars to a Map of Ids as
keys and models as values:
24 of 33 29/03/23, 8:13 pm
Java 8 Stream API - You Learn Code [Link]
Of course, you can do the same with any data structure or even a StringBuilder
as shown below:
25 of 33 29/03/23, 8:13 pm
Java 8 Stream API - You Learn Code [Link]
▪ [Link]
JAVA SPRING BOOT (), which
converts a stream of string to a string.
And many more aggregate functions that will not be analyzed in-depth in this article.
26 of 33 29/03/23, 8:13 pm
Java 8 Stream API - You Learn Code [Link]
27 of 33 29/03/23, 8:13 pm
Java 8 Stream API - You Learn Code [Link]
5. A Visualization
JAVA SPRING BOOT of Java 8 Stream
We can use the stream trace provided by Intellij IDEA to visualize the following
stream processing and see how the magic happens:
6. Conclusion
By now, you should have a good grasp of how streams work in Java and how to take
full advantage of all the methods offered by Java Stream API. You can find the
source code on our GitHub page.
7. Sources
28 of 33 29/03/23, 8:13 pm
Java 8 Stream API - You Learn Code [Link]
[1]: Stream(Java
SPRINGSEBOOT
12 & JDK 12 – Oracle
JAVA
Tags: core java java java stream filter java stream map java stream reduce streams
geonikpal
Related Posts
29 of 33 29/03/23, 8:13 pm
Java 8 Stream API - You Learn Code [Link]
D ATA S T R U C T U R E S &
J AVA J AVA ALGORITHMS
Java Classes & Objects How to Use the Java Break How to Implement the
Statement to Your Singleton Design Pattern in
Advantage Java
J AVA J AVA
LOAD MORE
30 of 33 29/03/23, 8:13 pm
Java 8 Stream API - You Learn Code [Link]
31 of 33 29/03/23, 8:13 pm
Java 8 Stream API - You Learn Code [Link]
32 of 33 29/03/23, 8:13 pm
Java 8 Stream API - You Learn Code [Link]
You Learn Code and all content copyright © 2022-2023 Contact / Privacy Policy / Terms and Conditions
DISCLAIMER:
All trademarks and registered trademarks appearing on You Learn Code are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries. You Learn
Code is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
33 of 33 29/03/23, 8:13 pm