Java 8 streams: iterate over Map of Lists

47,181

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.

Share:
47,181
waXve
Author by

waXve

Updated on January 25, 2020

Comments

  • waXve
    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
    Giovanni Botta over 9 years
    That should be .stream().collect I believe. Also you need to map the list of MyObject, something like elem -> elem.getValue().stream().map(e -> e.name)
  • nitishagar
    nitishagar over 9 years
    Forgot to add entrySet().stream() fixed that :)