This is my hash map:
JavaScript
x
HashMap<Customer, HashSet<Car>> carsBoughtByCustomers =
How can I get a new HashMap
that will contain for each customer the amount of cars, i.e. the size of the HashSet
?
I want to do this without loops, but using streams only.
My attempt:
JavaScript
HashMap<Customer, Integer> result = (HashMap<Customer, Integer>)
carsBoughtByCustomers.entrySet().stream()
.map(e -> e.getValue().size());
Advertisement
Answer
You need to apply a terminal operation in order to obtain a result from the stream, collect()
in this case, which expects a Collector
.
map()
– is an intermediate operation, it produces another stream, i.e. it’s meant to transform the stream-pipeline but not to generate a result. Therefore, a stream-statement like this myMap.entrySet().stream().map()
results to a Stream
, and is not assignable to a variable of type Map
.
JavaScript
Map<Customer,Integer> result = carsBoughtByCustomers.entrySet().stream()
.collect(Collectors.toMap(
Map.Entry::getKey,
entry -> entry.getValue().size()
));
Sidenotes:
- Writing code against interfaces like
Map
andSet
, not concrete types likeHashMap
andHashSet
, makes your code more flexible. See: What does it mean to “program to an interface”? - A stream without a terminal operation is perfectly valid, i.e. it would compile (if there are no errors is the code), but would not be executed.