在我的Java应用程序11,我想从一个存储库中获得产品更新。一个产品更新有updateId
和productIds
的名单进行更新。
updateId = X
更新进行更新没有产品编号,我还是要写信给我已经处理了更新X
另一个表; updateStatusRepository.setStatusProcessing(updateId)
和updateStatusRepository.setStatusProcessed(updateId)
仍然应该叫这个updateId
。ProductProcessingService
进行处理。就目前而言,groupingBy
和mapping
给我一套具有null
条目,而不是空集,这就是为什么我后来删除所有null
产品ID。
List<ProductUpdate> productUpdateList = updateStatusRepository.getProductUpdates();
Map<String, Set<String>> productUpdateMap = productUpdateList
.stream()
.collect(
Collectors.groupingBy(
ProductUpdate::getUpdateId,
Collectors.mapping(ProductUpdate::getProductNo, Collectors.toSet())));
productUpdateMap.forEach(
(updateId, productIds) -> {
try {
updateStatusRepository.setStatusProcessing(updateId);
productIds.remove(null);
if(!productIds.isEmpty()) {
productProcessingService.performProcessing(Lists.newArrayList(productIds));
}
updateStatusRepository.setStatusProcessed(updateId);
} catch (Exception e) {
//
}
});
我宁愿如果有可能以这样的方式来使用mapping
,它直接提供了一个空集,如果所有值都null
。
有没有一种方法能够完美地做到这一点?
你可以使用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
产品数量的元素,我们可能最终没有条目的地图对于一些版本ID,即在所有情况下,产品编号是null
为一个特定版本ID。
从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())));