通过流将列表转换为Java 8中具有父子关系的嵌套列表

问题描述 投票:0回答:2

Arraylist如下:

[{
  "id": 1,
  "parent_id": 0,
  "name": "Top1",
}, {
  "id": 2,
  "parent_id": 1,
  "name": "Second Layer1",
},{
  "id": 3,
  "parent_id": 0,
  "name": "Top2",
},{
  "id": 4,
  "parent_id": 1,
  "name": "Second Layer2",
}]

输出应该像:

[{
  "id": 1,
  "parent_id": 0,
  "name": "Top1",
  "children": [{
    "id": 2,
    "parent_id": 1,
    "name": "Second Layer1",
  }, {
    "id": 4,
    "parent_id": 1,
    "name": "Second Layer2",
  }]
}, {
  "id": 3,
  "parent_id": 0,
  "name": "Top2",
}]

我当前的解决方案是区分“顶层”和“第二层”,然后通过“ parent_id”将“第二层”转换为哈希表组,最后迭代“顶层”并匹配“顶层”的id ”和该哈希图的键。实现就像自爆:

List<Org> topLayers = list.stream().filter(org -> org.getParent_id==0).collect(Collectors.toList());

List<Org> secondLayers = list.stream().filter(org -> org.getParent_id!=0).collect(Collectors.toList());

Map<Long, Org> hashMap = secondLayers.stream().collect(Collectors.toMap(Org::parent_id, org -> org));

topLayers.stream().forEach(topOrg -> {
    topOrg.addChildren(hashMap.get(topOrg.getId()));
});

如您所见,找出它需要四个步骤。有没有更有效的解决方法?

Extension:如果超过2层怎么办?像递归

java recursion stream
2个回答
0
投票

您可以简单地使用基于parentID的分组方式对所有数据进行分组,然后将每个父级分配给该列表:

Map<Long, List<Org>> result = list.stream()
  .collect(Collectors.groupingBy(Org::parent_id));

然后:

list.stream().filter(org -> org.getParent_id==0).forEach(v -> {
    v.addChildren(result.get(v.getId()));
});

我们可以有很多方法来做到这一点。您也可以尝试其他人。


0
投票

您已经说过了,递归。

convert(List src, List target) {
    for each item with parent id as (target is empty ? 0 : target's id):
        add it to (target is empty ? target : target's children)
        convert(src, item)
}
© www.soinside.com 2019 - 2024. All rights reserved.