Stream operations enable Java developers to perform tasks with ease and elegance. In this article, I use two examples to introduce two Stream APIs, .collect()
and .sorted()
.
Turn A List Into A Map Using .collect
We have a list of Customer
, and each Customer
has a field named customerId
. The goal is to create a map that uses the customerId
as key, and the Customer
object reference as value.
class Customer {
private String customerId;
public Customer(String id){ this.customerId = id; }
public String getCustomerId(){ return this.customerId; }
}
class Example {
public static void main(String[] args){
List<Customer> customers = new ArrayList<>();
customers.add(new Customer("001"))
customers.add(new Customer("002"));
/*
create a map that uses the customerId as key,
and the Customer object reference as value. Insert your code below:
*/
}
}
I used to write:
Map<String, Customer> map = new HashMap<>();
for(Customer c : customers){
map.putIfAbsent(c.getCustomerId(), c);
}
But since I learned how to use stream, I can also write:
Map<String, Customer> map = customers.stream().collect(Collectors.toMap(Customer::getCustomerId, customer -> customer));
Let’s break down the above one-liner step by step:
customers.stream()
: Thestream()
method is called on thecustomers
list, which converts it into a stream. A stream is a sequence of elements that can be processed sequentially or in parallel using stream operations..collect(Collectors.toMap(Customer::getCustomerId, customer -> customer))
:.collect
is a terminal operation in the Java 8 Stream API. In this example, the stream elements are collected into a map using thetoMap
collector.Customer::getCustomerId
: This is a method reference that refers to thegetCustomerId()
method of theCustomer
class. It is used as the key mapper for thetoMap
collector, meaning it extracts thecustomerId
from eachCustomer
object to use as the key in the resulting map.customer -> customer
: This lambda expression represents the value mapper for thetoMap
collector. It specifies that the originalCustomer
object should be used as the value in the resulting map.
🤔 This is a good point to stop and ponder. Can you answer the following two questions?
1. Can you write out all entries in the map from the above code example?
2. You have a list of Recipe
and each Recipe
has a field recipeName
, can you use .collect
to create a map with recipeName
as the key and the Recipe
object reference as its value?
Sort A List of Object Using .sorted
There is a list of Players and each Player
has a field named score
. The field score
is a double. The goal is to sort the list based on each Player’s score in ascending order.
class Player {
private String id;
private double score;
public Player(String id, double score){ ... }
public double getScore(){return this.score; }
}
class Example2 {
public static void main(String[] args){
List<Player> players = new ArrayList<>();
players.add(new Player("001", 89.3));
players.add(new Player("002", 79.8));
/*
sort the player list based on each Player's score in ascending order.
Insert your code below:
*/
}
}
I used to use List.sort
like below:
players.sort(Comparator.comparingDouble(Player::getScore));
but since I learned how to use stream, I can also write:
players.stream()
.sorted(Comparator.comparingDouble(Player::getScore))
.toList();
Let’s break it down step by step:
.stream()
: Thestream()
method is called on theplayers
collection, which converts it into a stream. A stream is a sequence of elements that can be processed sequentially or in parallel using stream operations..sorted(Comparator.comparingDouble(Player::getScore))
: Thesorted
method is called on the stream to sort the elements based on thePlayer
object'sscore
field. This method requires aComparator
to define the sorting order.Comparator.comparingDouble(Player::getScore)
: This creates a comparator using thecomparingDouble
method of theComparator
class. ThecomparingDouble
method takes a function as an argument, and in this case, we use a method referencePlayer::getScore
. It means we're comparing thePlayer
objects based on theirscore
field, which should be of typedouble
..toList()
: This terminal operation collects the elements of the sorted stream into a list.
After performing all the stream operations, the final result is a new list containing the elements of the players collection, sorted in ascending order based on the score
field of each Player
object.
Thank you for reading! If you enjoyed reading this tutorial please consider share it or give it a 👏 clap (or long press for up to 50 claps! A cool hidden trick in my opinion 😁).