【问题标题】:java 8 stream collector mapping List<List> to Listjava 8 流收集器映射 List<List> 到 List
【发布时间】:2017-05-10 11:56:53
【问题描述】:

假设我有这门课:

public class Employee{

  private int id;
  private List<Car> cars;
//getters , equals and hashcode by id
}

public class Car {
  private String name;

}

我有一份员工名单(相同的 ID 可能重复):

List<Employee> emps =  ..

Map<Employee, List<List<Car>>> resultMap = emps.stream().collect(
            Collectors.groupingBy(Function.identity(),
                    Collectors.mapping(Employee::getCars, Collectors.toList());

这给了我Map&lt;Employee, List&lt;List&lt;Car&gt;&gt;&gt;, 我怎样才能得到一个Map&lt;Employee, List&lt;Car&gt;(像一个平面列表)?

【问题讨论】:

    标签: java collections java-8 java-stream


    【解决方案1】:

    当您根本不进行任何分组时,我不明白您为什么使用groupingBy。您似乎只需要创建一个Map,其中Employee 中的键和值是Employee 的汽车:

    Map<Employee, List<Car> map =
        emps.stream().collect(Collectors.toMap(Function.identity(),Employee::getCars);
    

    如果您为了加入相同Employee 的两个实例而进行分组,您仍然可以将toMap 与合并功能一起使用:

    Map<Employee, List<Car> map =
        emps.stream()
            .collect(Collectors.toMap(Function.identity(),
                                      Employee::getCars,
                                      (v1,v2)-> {v1.addAll(v2); return v1;},
                                      HashMap::new);
    

    请注意,这会改变由Employee::getCars 返回的一些原始Lists,因此您可能希望创建一个新的List,而不是将一个列表的元素添加到另一个列表中。

    【讨论】:

    • 是的,很抱歉我没有正确阅读案例。你的解决方案很好。我的意思是使用 flatMap 将列表列表转换为单个列表,但由于它位于 toMap 收集器中,因此您的解决方案要好得多。
    • 你能再帮忙一次吗?如果在 Employee 类中我们有 Set 汽车,但我想得到 Map>
    • @user1321466 在这种情况下,您可以将Employee::getCars 替换为e-&gt;new ArrayList&lt;Car&gt;(e.getCars())
    猜你喜欢
    • 1970-01-01
    • 2016-08-19
    • 1970-01-01
    • 2019-04-19
    • 1970-01-01
    • 2019-01-08
    • 1970-01-01
    • 2014-09-15
    相关资源
    最近更新 更多