I have map Map<Nominal, Integer> with objects and their counts:
a -> 3
b -> 1
c -> 2
And I need to get such a List<Nominal> from it:
a
a
a
b
c
c
How can I do this using the Stream API?
3 Answers 3
We can use Collections::nCopies to achieve the desired result:
private static <T> List<T> transform(Map<? extends T, Integer> map) {
return map.entrySet().stream()
.map(entry -> Collections.nCopies(entry.getValue(), entry.getKey()))
.flatMap(Collection::stream)
.collect(Collectors.toList());
}
Remark
In the demo, I changed the key-type of the Map from Nominal to Object since the definition of Nominal was not provided. Changing the key-type, however, does not influence the solution.
1 Comment
.map and .flatMap calls can be combined into a single .flatMap: map.entrySet().stream().flatMap(e -> Collections.nCopies(e.getValue(), e.getKey()).stream()).toList().Stream the entries and use flatMap to generate multiple copies of each key based on the value.
List<Nominal> expanded = map.entrySet().stream()
.flatMap(e -> generate(e::getKey).limit(e.getValue()))
.collect(toList());
Comments
Less concise than some other solutions, but here's a solution using Stream.mapMulti, which was added in Java 16:
List<Nominal> list = map.entrySet().stream()
.<Nominal>mapMulti((e, c) -> {
for (int i = 0; i < e.getValue(); i++) {
c.accept(e.getKey());
}
})
.toList();
Javadoc
API Note:
This method is similar to
flatMapin that it applies a one-to-many transformation to the elements of the stream and flattens the result elements into a new stream. This method is preferable toflatMapin the following circumstances:
- When replacing each stream element with a small (possibly zero) number of elements. Using this method avoids the overhead of creating a new Stream instance for every group of result elements, as required by
flatMap.- When it is easier to use an imperative approach for generating result elements than it is to return them in the form of a Stream.
Comments
Explore related questions
See similar questions with these tags.
Nominal?Nominal- it is Enum