Java 8 streams: iterate over Map of Lists
Solution 1
Map<String, List<String>> result = anotherHashMap
.entrySet().stream() // Stream over entry set
.collect(Collectors.toMap( // Collect final result map
Map.Entry::getKey, // Key mapping is the same
e -> e.getValue().stream() // Stream over list
.sorted(Comparator.comparingLong(MyObject::getPriority)) // Sort by priority
.map(MyObject::getName) // Apply mapping to MyObject
.collect(Collectors.toList())) // Collect mapping into list
);
Essentially, you stream over each entry set and collect it into a new map. To compute the value in the new map, you stream over the List<MyOjbect>
from the old map, sort, and apply a mapping and collection function to it. In this case I used MyObject::getName
as the mapping and collected the resulting names into a list.
Solution 2
For generating another map, we can have something like following:
HashMap<String, List<String>> result = anotherHashMap.entrySet().stream().collect(Collectors.toMap(elem -> elem.getKey(), elem -> elem.getValue() // can further process it);
Above I am recreating the map again, but you can process the key or the value according to your needs.
Solution 3
Map<String, List<String>> result = anotherHashMap.entrySet().stream().collect(Collectors.toMap(
Map.Entry::getKey,
e -> e.getValue().stream()
.sorted(comparing(MyObject::getPriority))
.map(MyObject::getName)
.collect(Collectors.toList())));
Similar to answer of Mike Kobit, but sorting is applied in the correct place (i.e. value is sorted, not map entries) and more concise static method Comparator.comparing
is used to get Comparator for sorting.
waXve
Updated on January 25, 2020Comments
-
waXve over 4 years
I have the following Object and a Map:
MyObject String name; Long priority; foo bar; Map<String, List<MyObject>> anotherHashMap;
I want to convert the Map in another Map. The Key of the result map is the key of the input map. The value of the result map ist the Property "name" of My object, ordered by priority.
The ordering and extracting the name is not the problem, but I could not put it into the result map. I do it the old Java 7 way, but it would be nice it is possible to use the streaming API.
Map<String, List<String>> result = new HashMap<>(); for (String identifier : anotherHashMap.keySet()) { List<String> generatedList = anotherHashMap.get(identifier).stream()...; teaserPerPage.put(identifier, generatedList); }
Has anyone an idea? I tried this, but got stuck:
anotherHashMap.entrySet().stream().collect(Collectors.asMap(..., ...));
-
Giovanni Botta over 9 yearsThat should be
.stream().collect
I believe. Also you need to map the list ofMyObject
, something likeelem -> elem.getValue().stream().map(e -> e.name)
-
nitishagar over 9 yearsForgot to add entrySet().stream() fixed that :)