展平地图中的列表列表

时间:2019-05-08 22:13:27

标签: java java-8 java-stream

我有一个订单流(来源是订单列表)。 每个订单都有一个客户和一个OrderLine列表。

我想要实现的是在一张简单的列表中以客户为关键的地图,并将属于该客户的所有订单行作为值。

通过执行以下操作,我现在管理的内容返回Map<Customer>, List<Set<OrderLine>>>

orders
  .collect(
    Collectors.groupingBy(
      Order::getCustomer,
      Collectors.mapping(Order::getOrderLines, Collectors.toList())
    )
  );

我正在寻找直接从订单流中获取Map<Customer, List<OrderLine>>的方法,或者通过某种方式使我上面获得的Map<Customer>, List<Set<OrderLine>>>流中的列表扁平化。

2 个答案:

答案 0 :(得分:3)

另一种选择是使用简单的forEach调用:

Map<Customer, List<OrderLine>> map = new HashMap<>();

orders.forEach(
    o -> map.computeIfAbsent(
            o.getCustomer(),
            c -> new ArrayList<OrderLine>()
        ).addAll(o.getOrderLines())
);

然后您可以继续在map.entrySet().stream()上对结果使用流。

对于groupingBy方法,请尝试Flat-Mapping Collector for property of a Class using groupingBy

答案 1 :(得分:3)

您可以简单地使用Collectors.toMap

类似

    orders
        .stream()
        .collect(Collectors
                .toMap(Order::getCustomer
                        , Order::getOrderLines
                        , (v1, v2) -> { List<OrderLine> temp = new ArrayList<>(v1); 
                                        temp.addAll(v2); 
                                        return temp;});

toMap函数的第三个参数是合并函数。如果您未明确提供该密码,并且有重复的密码,则它将在完成操作时引发错误。