如何使用java8流来计算值的总和以及按语句分组

时间:2016-11-04 00:54:45

标签: java java-8 java-stream

我有一个Person类,它有性别和年龄字段。我希望通过以下代码获得每个性别的年龄总和。

public void test() {
        List<Person> roster = new ArrayList();

        Map<Integer, Integer> totalAgeByGender =
                roster
                        .stream()
                        .collect(
                                Collectors.groupingBy(
                                        Person::getGender,
                                        Collectors.reducing(
                                                0,
                                                Person::getAge,
                                                Double::sum)));
    }

    static class Person {

        private int gender;
        private double age;

        public int getGender() {
            return gender;
        }

        public double getAge() {
            return age;
        }
    }
}

我遇到编译错误,上面的代码如下:

Bad return type in method reference: cannot convert double to U. 

它抱怨蒸汽声明Double::sum的最后一部分。如果我将年龄类型更改为整数并在上面的代码中使用Integer::sum,它可以正常工作。在这种情况下,我徘徊Double :: sum的错误。

此外,是否可以按性别分组并从一个蒸汽语句中返回Map<Integer, List<Person>>

1 个答案:

答案 0 :(得分:1)

你在这里遇到以下两个小问题:(1)你的身份被解释为整数; (2)地图的值为Double(s)。

Map<Integer, Double> totalAgeByGender = // not Map<Integer, Integer>
    roster.stream()
        .collect(Collectors.groupingBy(
            Person::getGender,
            Collectors.reducing(
                0d, // not 0
                Person::getAge,
                Double::sum)));

如下所述,使用Collectors.summingDouble可以使这更简洁,更不容易出错:

Map<Integer, Double> totalAgeByGender = roster.stream()
    .collect(Collectors.groupingBy(
        Person::getGender,
        Collectors.summingDouble(Person::getAge)));

您可以轻松按性别(性别)进行分组:

Map<Integer, List<Person>> sexToPeople = roster.stream()
    .collect(Collectors.groupingBy(
        Person::getGender, 
        Collectors.toList()));