要点:我们试图尽可能用java 8流和lambdas重写旧的Java代码。
问题: 我有一个地图,其键是一个字符串,值是用户定义的对象列表。
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));
这里的人根据姓名的起始字符进行分组。
我想在地图中找到每个关键字列表中人员的平均年龄。
同样,我已经尝试过stackoverflow中提到的很多东西,但没有一个与我的案例匹配,或者很少在语法上不起作用。
提前致谢!
答案 0 :(得分:5)
你没有说明你希望如何(或者如果)想要存储年龄,所以我现在只将它作为一个打印声明。然而,它就像迭代Map
中的每个条目并打印每个List
的平均值(在将Person
对象映射到它们的年龄之后)一样简单:
personMap.forEach((k, v) -> {
System.out.println("Average age for " + k + ": " + v.stream().mapToInt(Person::getAge).average().orElse(-1));
});
如果您想将其存储在另一个Map
中,那么您可以非常轻松地将其收集到一个:
personMap.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue()
.stream()
.mapToInt(Person::getAge)
.average()
.orElse(-1)));
注意:如果不存在平均值,则返回-1
,这假设Person
中存在一个名为getAge
的getter方法,返回{{1} }}
答案 1 :(得分:3)
你可以这样做:
// 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())
));