Streaming a Map
Filter, sort and rebuild maps through entrySet, and keep the order you asked for.
Open this lesson in the learning hubKey points
- A Map has no
stream()of its own. StreamkeySet(),values()orentrySet()instead. entrySet()is the useful one, because the key and the value stay together through the whole pipeline.Map.Entry.comparingByValue()andcomparingByKey()are ready made comparators for sorting.- Sorting alone is not enough: collect into a
LinkedHashMapor the order is thrown away again. - The four argument
toMaptakes a merge function and a map factory, which is how you avoid duplicate key exceptions. - Do not modify the map you are streaming. Build a new one and swap it in.
Example
import java.util.*;
import java.util.stream.*;
public class Main {
public static void main(String[] args) {
Map<String, Integer> stock = new LinkedHashMap<>();
stock.put("apple", 12);
stock.put("fig", 0);
stock.put("pear", 7);
System.out.println("keys : " + stock.keySet().stream().sorted().toList());
System.out.println("total : " + stock.values().stream().mapToInt(Integer::intValue).sum());
// entrySet() is the workhorse: the key and the value stay together.
System.out.println("in stock: " + stock.entrySet().stream()
.filter(e -> e.getValue() > 0)
.map(e -> e.getKey() + "=" + e.getValue())
.toList());
// Flip a map. The merge function decides what happens on a duplicate key.
Map<Integer, String> flipped = stock.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey, (a, b) -> a, TreeMap::new));
System.out.println("flipped : " + flipped);
// Sort by value, then keep that order by collecting into a LinkedHashMap.
Map<String, Integer> ranked = stock.entrySet().stream()
.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
(a, b) -> a, LinkedHashMap::new));
System.out.println("ranked : " + ranked);
// Building a map from a list is the other direction.
System.out.println("built : " + Stream.of("ada", "grace")
.collect(Collectors.toMap(n -> n, String::length, (a, b) -> a, TreeMap::new)));
}
}
Stream entrySet, and collect into a LinkedHashMap when the new order matters.
This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Streams course, and every lesson in it is listed on the Streams contents page.