如何在Java 8中展开Map列表

7

我有一个需求,其中我有一组映射列表

[{Men=1},{Men=2, Women=3},{Women=2,Boys=4}]

现在我需要将它转换为一个flatMap,以便它看起来像这样。
Gender=countOfValues

在上面的示例中,输出将会是:
{Men=3,Women=5,Boys=4}

目前我有以下代码:

private Map<String, Long> getGenderMap(
        List<Map<String, Long>> genderToCountList) {
    Map<String, Long> gendersMap = new HashMap<String, Long>();
    Iterator<Map<String, Long>> genderToCountListIterator = genderToCountList
            .iterator();
    while (genderToCountListIterator.hasNext()) {
        Map<String, Long> genderToCount = genderToCountListIterator.next();
        Iterator<String> genderToCountIterator = genderToCount.keySet()
                .iterator();
        while (genderToCountIterator.hasNext()) {
            String gender = genderToCountIterator.next();
            if (gendersMap.containsKey(gender)) {
                Long count = gendersMap.get(gender);
                gendersMap.put(gender, count + genderToCount.get(gender));
            } else {
                gendersMap.put(gender, genderToCount.get(gender));
            }
        }
    }
    return gendersMap;
}

我们如何使用Java8的lambda表达式来编写这段代码?

3
为什么你要使用迭代器和while循环?增强的for循环更简单,并且自Java 5以来已经存在,而你显然在使用泛型,因此你也是在使用Java 5。 - Andreas
1
这似乎是很多代码,期望有人在这里为您重写。您是否遇到了某些具体的问题?如果是这样,您应该针对该问题提出一个问题。 - Brick
1个回答

20

我不会在这种情况下使用任何lambda表达式,但我已经使用了Java 8中引入的Map.merge和方法引用。

Map<String, Long> result = new HashMap<>();
for (Map<String, Long> map : genderToCountList)
    for (Map.Entry<String, Long> entry : map.entrySet())
        result.merge(entry.getKey(), entry.getValue(), Long::sum);

你也可以使用 Stream 来实现这一点:

return genderToCountList.stream().flatMap(m -> m.entrySet().stream())
           .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, Long::sum));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接