s-h*_*ins 6 java java-stream collectors
在我的Java 11应用程序中,我想从存储库获取产品更新.一个产品更新有一个updateId和productIds要更新的列表.
如果没有应该更新的产品编号以进行更新updateId = X,我仍然希望写入另一个我已处理更新的表X; updateStatusRepository.setStatusProcessing(updateId)并且updateStatusRepository.setStatusProcessed(updateId)应该仍然需要这个updateId.
如果存在产品更新,则应在中进行处理ProductProcessingService.
现在,groupingBy并mapping给我一个带有null条目而不是空集的Set,这就是我之后删除所有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) {
//
}
});
Run Code Online (Sandbox Code Playgroud)
我更喜欢是否可以以mapping这样的方式使用它,如果所有值都是直接传递空集null.
有没有办法优雅地做到这一点?
Fed*_*ner 10
你可以使用Collectors.filtering:
Map<String, Set<String>> productUpdateMap = productUpdateList
.stream()
.collect(Collectors.groupingBy(
ProductUpdate::getVersionId,
Collectors.mapping(ProductUpdate::getProductNo,
Collectors.filtering(Objects::nonNull,
Collectors.toSet()))));
Run Code Online (Sandbox Code Playgroud)
我认为Collectors.filtering适合您的确切用例:它将过滤掉null产品编号,如果所有产品编号都是空的,则留空null.
编辑:请注意,在这种情况下,使用Collectors.filtering下游收集器与Stream.filter收集前使用不同.在后一种情况下,如果我们null在收集之前过滤掉带有产品编号的元素,我们最终可能会得到一个没有某些版本ID条目的地图,即如果所有产品编号都是null针对一个特定版本ID.
来自Collectors.filteringdocs:
API注意:
的
filtering()在多级降低使用时,诸如下游收集器是最有用的groupingBy或partitioningBy.例如,给定一个流Employee,以累积每个部门中具有高于特定阈值的薪水的员工:Run Code Online (Sandbox Code Playgroud)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())));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
181 次 |
| 最近记录: |