简体   繁体   中英

How to iterate and work on the values of a map whose values are a list of elements using java 8 streams and lambdas

Gist: We are trying to rewrite our old java code with java 8 streams and lambdas wherever possible.

Question: I have a map whose key is a string and values are list of user defined objects.

Map<String, List<Person>> personMap = new HashMap<String, List<Person>>();
personMap.put("A", Arrays.asList(person1, person2, person3, person4));
personMap.put("B", Arrays.asList(person5, person6, person7, person8));

Here the persons are grouped based on their name's starting character.

I want to find the average age of the persons on the list for every key in the map.

For the same, i have tried many things mentioned in stackoverflow but none is matching with my case or few are syntactically not working.

Thanks In Advance!

You didn't specify how (or if) you would like the ages to be stored, so I have it as just a print statement at the moment. Nevertheless, it's as simple as iterating over each entry in the Map and printing the average of each List (after mapping the Person objects to their age):

personMap.forEach((k, v) -> {
    System.out.println("Average age for " + k + ": " + v.stream().mapToInt(Person::getAge).average().orElse(-1));
});

If you would like to store it within another Map , then you can collect it to one pretty easily:

personMap.entrySet()
         .stream()
         .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue()
                                                            .stream()
                                                            .mapToInt(Person::getAge)
                                                            .average()
                                                            .orElse(-1)));

Note : -1 is returned if no average is present, and this assumes a getter method exists within Person called getAge , returning an int .

You can do it like so:

// this will get the average over a list
Function<List<Person>, Double> avgFun = (personList) ->
   personList.stream()
      .mapToInt(Person::getAge)
      .average()
      .orElseGet(null);

// this will get the averages over your map
Map<String, Double> result = personMap.entrySet().stream()
   .collect(Collectors.toMap(
      Map.Entry::getKey,
      entry -> avgFun.apply(entry.getValue())
   ));

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