lca*_*ito 11 java lambda java-8 java-stream collectors
我有以下课程.
class Person {
String name;
LocalDate birthday;
Sex gender;
String emailAddress;
public int getAge() {
return birthday.until(IsoChronology.INSTANCE.dateNow()).getYears();
}
public String getName() {
return name;
}
}
Run Code Online (Sandbox Code Playgroud)
我希望能够按年龄分组,然后收集人名列表而不是Person对象本身; 所有这些都在一个很好的lamba表达式中.
为了简化所有这些,我将链接我当前的解决方案,该解决方案按年龄存储分组结果,然后迭代它以收集名称.
ArrayList<OtherPerson> members = new ArrayList<>();
members.add(new OtherPerson("Fred", IsoChronology.INSTANCE.date(1980, 6, 20), OtherPerson.Sex.MALE, "fred@example.com"));
members.add(new OtherPerson("Jane", IsoChronology.INSTANCE.date(1990, 7, 15), OtherPerson.Sex.FEMALE, "jane@example.com"));
members.add(new OtherPerson("Mark", IsoChronology.INSTANCE.date(1990, 7, 15), OtherPerson.Sex.MALE, "mark@example.com"));
members.add(new OtherPerson("George", IsoChronology.INSTANCE.date(1991, 8, 13), OtherPerson.Sex.MALE, "george@example.com"));
members.add(new OtherPerson("Bob", IsoChronology.INSTANCE.date(2000, 9, 12), OtherPerson.Sex.MALE, "bob@example.com"));
Map<Integer, List<Person>> collect = members.stream().collect(groupingBy(Person::getAge));
Map<Integer, List<String>> result = new HashMap<>();
collect.keySet().forEach(key -> {
result.put(key, collect.get(key).stream().map(Person::getName).collect(toList()));
});
Run Code Online (Sandbox Code Playgroud)
不理想,为了学习,我希望有一个更优雅和更好的解决方案.
Tun*_*aki 13
使用"分组"流时Collectors.groupingBy,可以使用自定义对值指定缩减操作Collector.在这里,我们需要使用Collectors.mapping,它接受一个函数(映射是什么)和一个收集器(如何收集映射的值).在这种情况下,映射是Person::getName,即返回Person名称的方法引用,我们将其收集到a中List.
Map<Integer, List<String>> collect =
members.stream()
.collect(Collectors.groupingBy(
Person::getAge,
Collectors.mapping(Person::getName, Collectors.toList()))
);
Run Code Online (Sandbox Code Playgroud)