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.