You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Java Stream按姓氏分组并提取用户名字段?

问题

我有一个List<Person>集合,可以通过Java Stream按姓氏分组,代码示例如下:

Map<String, List<Person>> persons.stream()
    .collect(Collectors.groupingBy(Person::getLastName));

但我希望按姓氏分组后得到对应的用户名单,例如姓氏为"Smith"时,对应["Jane","John"]。是否存在带值提取器的groupingBy()用法?我预想的代码如下:

Map<String, List<String>> persons.stream()
    .collect(Collectors.groupingBy(Person::getLastName, Person::getFirstName));
解决方案

你预想的写法不符合API规范,groupingBy的第二个参数需要传入一个Collector实现,而非直接的字段提取函数。要实现分组后提取指定字段的需求,需要结合Collectors.mapping()来完成——它负责将分组后的每个Person对象转换为目标字段值,再收集为列表。

正确实现代码如下:

Map<String, List<String>> groupedNames = persons.stream()
    .collect(Collectors.groupingBy(
        Person::getLastName, // 分组键:姓氏
        Collectors.mapping(
            Person::getFirstName, // 值转换:提取名字
            Collectors.toList() // 收集为列表
        )
    ));

代码说明

  • Person::getLastName:作为分组的键提取器,决定每个元素归属的分组;
  • Collectors.mapping(Person::getFirstName, Collectors.toList()):作为分组的下游收集器,先将每个Person对象映射为名字字符串,再将这些字符串收集为List<String>,作为对应分组的值。

执行这段代码后,就能得到你期望的结构:键为姓氏字符串,值为对应姓氏下所有人的名字列表。

内容的提问来源于stack exchange,提问作者Garret Wilson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 22:39:52