Вы можете использовать Collectors.filtering
:
Map<String, Set<String>> productUpdateMap = productUpdateList
.stream()
.collect(Collectors.groupingBy(
ProductUpdate::getVersionId,
Collectors.mapping(ProductUpdate::getProductNo,
Collectors.filtering(Objects::nonNull,
Collectors.toSet()))));
Я думаю, Collectors.filtering
соответствует вашему конкретному случаю использования: он отфильтрует null
номеров продуктов, оставляя пустой набор, если все номера продуктов окажутся null
.
РЕДАКТИРОВАТЬ: Обратите внимание, что в этом случае использование Collectors.filtering
в качестве выходного коллектора не то же самое, что Stream.filter
перед сбором. В последнем случае, если мы отфильтровали элементы с номером продукта null
перед сбором, мы могли бы получить карту без записей для какого-либо идентификатора версии, т. Е. Если все номера продуктов равны null
для одного конкретного идентификатора версии.
Из Collectors.filtering
документов:
API Примечание:
Коллекторы filtering()
наиболее полезны при многоуровневом понижении, например, на groupingBy
или partitioningBy
. Например, с учетом потока Employee
, чтобы накапливать сотрудников в каждом отделе, у которых зарплата выше определенного порога:
Map<Department, Set<Employee>> wellPaidEmployeesByDepartment
= employees.stream().collect(
groupingBy(Employee::getDepartment,
filtering(e -> e.getSalary() > 2000,
toSet())));
Фильтрующий коллектор отличается от операции filter()
потока. В этом примере предположим, что в каком-либо отделе нет сотрудников, чья зарплата выше порога. Использование фильтрующего коллектора, как показано выше, приведет к отображению из этого отдела в пустой Set
. Если вместо этого будет выполнена операция потока filter()
, то для этого отдела вообще не будет отображений.
РЕДАКТИРОВАТЬ 2: Я думаю, что стоит упомянуть альтернативу, предложенную @Holger в комментариях:
Map<String, Set<String>> productUpdateMap = productUpdateList
.stream()
.collect(Collectors.groupingBy(
ProductUpdate::getVersionId,
Collectors.flatMapping(pu -> Stream.ofNullable(pu.getProductNo()),
Collectors.toSet())));