我有以下用例。我有一个具有以下结构的嵌套地图:
Map<String, Map<WorkType, List<CostLineItem>>>
我必须遍历地图并获取CLObject的列表。如果列表中的单个条目的标识符为null。我必须为每个EnumType生成唯一的标识符。我不确定如何使用流吗?遵循迭代逻辑将明确我要完成的事情
for(Map.Entry<String, Map<WorkType, List<CostLineItem>>> cliByWorkTypeIterator: clisByWorkType.entrySet()) {
Map<WorkType, List<CostLineItem>> entryValue = cliByWorkTypeIterator.getValue();
for(Map.Entry<WorkType, List<CostLineItem>>cliListIterator : entryValue.entrySet()) {
List<CostLineItem> clis = cliListIterator.getValue();
//if any CLI settlementNumber is zero this means we are in standard upload
//TODO: Should we use documentType here? Revisit this check while doing dispute file upload
if(clis.get(0).getSettlementNumber() == null) {
clis.forEach(f -> f.toBuilder().settlementNumber(UUID.randomUUID().toString()).build());
}
}
}
嵌套的循环使代码位的模板变脏。有人可以在这里帮助我吗?
答案 0 :(得分:1)
您可以使用flatMap
遍历所有内部List<CostLineItem>
的所有Map
值。
clisByWorkType.values() // returns Collection<Map<WorkType, List<CostLineItem>>>
.stream() // returns Stream<Map<WorkType, List<CostLineItem>>>
.flatMap(v->v.values().stream()) // returns Stream<List<CostLineItem>>
.filter(clis -> clis.get(0).getSettlementNumber() == null) // filters that Stream
.forEach(clis -> {do whatever logic you need to perform on the List<CostLineItem>});
答案 1 :(得分:0)
clisByWorkType.values()
.stream()
.flatMap(e -> e.values().stream())
.filter(clis -> clis.get(0).getSettlementNumber() == null)
.flatMap(Collection::stream)
.forEach(f -> f.toBuilder().settlementNumber(UUID.randomUUID().toString()).build());
答案 2 :(得分:0)
以下等效于您的for循环:
clisByWorkType.entrySet()
.map(Map.Entry::getValue) // cliByWorkTypeIterator.getValue();
.flatMap(m -> m.entrySet().stream())
.map(Map.Entry::getValue)
.map(CostLineItem::getValue)
.filter(clis.get(0).getSettlementNumber() == null) //filter before flattening
.flatMap(List::stream)
.forEach(f -> f.toBuilder().settlementNumber(UUID.randomUUID().toString()).build());