Java 8 使用自定义收集器进行分组?

标签 java lambda java-8 java-stream collectors

我有以下类(class)。

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;
    }
}

我希望能够按年龄分组,然后收集人名列表而不是 Person 对象本身;所有这些都在一个漂亮的兰巴表达式中。

为了简化这一切,我链接了我当前的解决方案,该解决方案存储按年龄分组的结果,然后对其进行迭代以收集名称。

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()));
});

Current solution

并不理想,为了学习,我希望有一个更优雅、更高效的解决方案。

最佳答案

将流分组为 Collectors.groupingBy 时,您可以使用自定义Collector 指定对值进行缩减操作。在这里,我们需要使用Collectors.mapping ,它需要一个函数(映射是什么)和一个收集器(如何收集映射值)。在本例中,映射是 Person::getName,即返回 Person 名称的方法引用,我们将其收集到 List 中。

Map<Integer, List<String>> collect = 
    members.stream()
           .collect(Collectors.groupingBy(
               Person::getAge,
               Collectors.mapping(Person::getName, Collectors.toList()))
           );

关于Java 8 使用自定义收集器进行分组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39829961/

相关文章:

java - 在 try block 中返回 vs 在 block 后返回

java - 避免在使用层次结构参数的操作中进行静态绑定(bind)

java - 构建一个 jar 以包含未获得执行权限的 shell 脚本文件

java - 在 Java 8 中使用 lambda 表达式有什么优点?

java - 如何获取 Java 8 方法引用的 MethodInfo?

java - 禁用 java 日志轮换

c# - 过滤器需要通过引用传递才能附加到它

c - 新的 C11 标准支持 lambda 吗?

Java 使用 Collections.reverseOrder() 按值降序排列 TreeMap

java - List.sublist(n,m) 的 View 是什么?