简体   繁体   中英

Java 8 streams: iterate over Map of Lists

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(..., ...));
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.

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 (ie value is sorted, not map entries) and more concise static method Comparator.comparing is used to get Comparator for sorting.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM