Сведение списка списков на карте - PullRequest
2 голосов
/ 09 мая 2019

У меня есть поток заказов (источником является список заказов).У каждого заказа есть Клиент и список 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 ]

3 голосов
/ 09 мая 2019

Вы можете просто использовать 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 - это функция слияния. Если вы не укажете это явно, и у вас есть дубликат ключа, он выдаст ошибку при завершении операции.

3 голосов
/ 09 мая 2019

Другой вариант - использовать простой вызов 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 для свойства класса с использованием groupingBy

...