Java Streams - 使用 GroupingBy 和计数收集到 Map,但如果特定字段为 Null,则计数为 0
Java Streams - Collecting to a Map With GroupingBy and Counting, But Count 0 If A Specific Field Is Null
为了避免 "duplicate hunters" 提出问题,我需要说明一下,我不认为我正在寻找的解决方案是过滤。我做了我的搜索,从来没有遇到提到过滤的答案。
我有一个带有 class 的对象列表:
class Person {
String gender;
String income;
String petName;
}
我想把这个List收集成一个map,按性别分组,统计他们拥有的宠物,当然如果petName为null就需要传0。
Map<String, Long> mapping = people
.stream()
.collect(Collectors.groupingBy(Person::gender, Collectors.counting());
在没有实现 Collector 接口的情况下,它有 5 个方法(因为我已经在尝试摆脱另一个自定义收集器)如果 petName
字段是 [=14,我怎样才能让它不计算对象=].
我可以受益于Java-11
首先将所有人员按性别分组,然后使用过滤收集器过滤掉姓名为空的人员。最后,使用计数下游收集器统计属于每个类别的元素数量。这是它的样子。
Map<String, Long> peopleCntByGender = people.stream()
.collect(Collectors.groupingBy(Person::getGender,
Collectors.filtering(p -> p.getPetName() != null,
Collectors.counting())));
但是,过滤收集器仅在 Java9 中可用,因此,如果您正在使用 Java8 并且无法轻松迁移到 Java9,请考虑编写您自己的自定义 filtering
收集器并在这里使用它。此 或 JDK 9 源代码可能有所帮助。
关于上面的评论(关于在性别没有宠物的情况下需要0
)我相信以下内容可以满足您的要求:
people.stream()
.collect(Collectors.toMap(Person::getGender,
person -> person.getPetName() == null ? 0L : 1L,
Long::sum));
为了避免 "duplicate hunters" 提出问题,我需要说明一下,我不认为我正在寻找的解决方案是过滤。我做了我的搜索,从来没有遇到提到过滤的答案。
我有一个带有 class 的对象列表:
class Person {
String gender;
String income;
String petName;
}
我想把这个List收集成一个map,按性别分组,统计他们拥有的宠物,当然如果petName为null就需要传0。
Map<String, Long> mapping = people
.stream()
.collect(Collectors.groupingBy(Person::gender, Collectors.counting());
在没有实现 Collector 接口的情况下,它有 5 个方法(因为我已经在尝试摆脱另一个自定义收集器)如果 petName
字段是 [=14,我怎样才能让它不计算对象=].
我可以受益于Java-11
首先将所有人员按性别分组,然后使用过滤收集器过滤掉姓名为空的人员。最后,使用计数下游收集器统计属于每个类别的元素数量。这是它的样子。
Map<String, Long> peopleCntByGender = people.stream()
.collect(Collectors.groupingBy(Person::getGender,
Collectors.filtering(p -> p.getPetName() != null,
Collectors.counting())));
但是,过滤收集器仅在 Java9 中可用,因此,如果您正在使用 Java8 并且无法轻松迁移到 Java9,请考虑编写您自己的自定义 filtering
收集器并在这里使用它。此
关于上面的评论(关于在性别没有宠物的情况下需要0
)我相信以下内容可以满足您的要求:
people.stream()
.collect(Collectors.toMap(Person::getGender,
person -> person.getPetName() == null ? 0L : 1L,
Long::sum));