1

我正在尝试处理具有以下格式的列表: List<Map<String, Map<String, Item>>Map<String, Map<String, List<Item>>哪里Item是一个包含两个属性的对象。

所以对于输入:

[
 <"A1", <"B1", Item_1>>,
 <"A1", <"B1", Item_2>>,
 <"A1", <"B2", Item_3>>,
 <"A2", <"B1", Item_4>>,
 <"A2", <"B2", Item_5>>,
 <"A2", <"B2", Item_6>>
]

输出应该是:

"A1" {
    <"B1", [Item_1, Item_2]>
    <"B2", [Item_3]>
}
"A2" {
    <"B1", [Item_4]>
    <"B2", [Item_5, Item_6]>
}

我尝试使用:

list.stream()
.flatMap(it -> it.entrySet().stream())
.collect(groupingBy(Map.Entry::getKey, Collectors.mapping(Map.Entry::getValues, Collectors.toList())));

但结果不是所需的,它返回Map<String, List<Map<String, Item>>>

{
"A1": [
   <"B1", Item_1>,
   <"B1", Item_2>,
   <"B2", Item_3>
  ]
"A2": [
   <"B1", Item_4>,
   <"B2", Item_5>,
   <"B2", Item_6>
  ]
}

您能否建议我如何通过 B_ 键进行分组?谢谢!

4

1 回答 1

0

B_如果您可以将条目展平为三元组数据结构,则可以使用键进行分组。虽然这对于地图条目是可行的,但在实现方面却相当混乱。更好的选择是创建自己的数据结构来临时保存这三个扁平属性。

这是我将在解决方案中进一步使用的类似行之一。

@Getter
@AllArgsConstructor
static class Holder {
    String a;
    String b;
    Item c;
}

现在另一个重要的一点是确保您将结构展平,直到最里面的条目,而不仅仅是Map在您的代码中共享的外部条目。这将需要嵌套flatMap使用。

list.stream()
        .flatMap(out -> out.entrySet().stream()
                .flatMap(e -> e.getValue().entrySet().stream()
                        .map(in -> new Holder(e.getKey(), in.getKey(), in.getValue()))))

到最后,您将拥有一个Stream<Holder>可以进一步分组两次并映射以推断预期结果的结果。这是完整的解决方案:

list.stream()
        .flatMap(out -> out.entrySet().stream()
                .flatMap(e -> e.getValue().entrySet().stream()
                        .map(in -> new Holder(e.getKey(), in.getKey(), in.getValue()))))
        .collect(Collectors.groupingBy(Holder::getA,
                Collectors.groupingBy(Holder::getB,
                        Collectors.mapping(Holder::getC,
                                Collectors.toList()))));
于 2020-10-21T07:24:47.070 回答