Java 8 Lambdas:将列表分组到映射中

59
我想从一个 List<Pojo> 转换为一个 Map<String, List<Pojo>>,其中 Map 的键是 Pojo 中的一个 String key 值。例如,给定以下内容:
Pojo 1: Key:a value:1
Pojo 2: Key:a value:2
Pojo 3: Key:b value:3
Pojo 4: Key:b value:4
我想得到一个大小为 2 的 Map<String, List<Pojo>>,其中键 "a" 具有 Pojos 1 和 2,键 "b" 具有 Pojos 3 和 4。
如何使用 Java 8 lambda 最好地实现此功能?

2
mapping(Function.identity(), toList()) 的意义是什么? identity() 意味着“没有映射”,那么为什么还要使用映射收集器呢?只需将其替换为单独的 toList(),然后您就会得到 groupingBy(t -> t.getKey(), HashMap::new, toList()),这几乎描述了 groupingBy 的默认值,除了当仅使用默认值时,结果不能保证是 HashMap。因此,当默认值适用时(即您不需要 HashMap),请像Eran的答案中所示使用默认值。 - Holger
感谢@Holger的提醒,我意识到我的代码示例存在缺陷,并在您的评论出现之前将其删除。你是完全正确的,感谢你的建议,我非常感激。 - Robert Bain
2个回答

116

使用简单的 groupingBy 变体:

Map<String, List<Pojo>> map = pojos
  .stream()
  .collect(
     Collectors.groupingBy(Pojo::getKey)
  );

54

另外,如果您想返回一个类似的映射,但是您希望该映射的值是Pojo的某个属性,您可以这样做:

Map<String, List<String>> map = pojos
  .stream()
  .collect(
    Collectors.groupingBy(
      Employee::getKey,
      Collectors.mapping(
        Pojo::getSomeStringProperty, 
        Collectors.toList()
      )
    )
  );

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接