在Java8中,通过流将列表转换为具有父子关系的嵌套列表
Arraylist如下所示:在Java8中,通过流将列表转换为具有父子关系的嵌套列表,java,recursion,java-8,java-stream,Java,Recursion,Java 8,Java Stream,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",
}, {
"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",
}]
我目前的解决方案是区分“顶层”和“第二层”,然后通过“父层id”将“第二层”转换为hashmap组,最后迭代“顶层”,并将“顶层”的id与该hashmap的键匹配。实现如下所示:
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, List<Org>> hashMap = secondLayers.stream().collect(Collectors.groupingBy(Org::parent_id));
topLayers.stream().forEach(topOrg -> {
topOrg.setChildren(hashMap.get(topOrg.getId()));
});
List topLayers=List.stream().filter(org->org.getParent_id==0.collect(Collectors.toList());
List secondLayers=List.stream().filter(org->org.getParent_id!=0).collect(Collectors.toList());
Map hashMap=secondLayers.stream().collect(Collectors.groupingBy(Org::parent_id));
topLayers.stream().forEach(topOrg->{
setChildren(hashMap.get(topOrg.getId());
});
正如您所看到的,这需要4个步骤才能解决。有没有更有效的方法来解决这个问题
扩展:如果有超过2层怎么办?与recursive类似,您可以简单地使用group by根据parentID对所有数据进行分组,然后将每个家长分配给该列表:
Map<Long, List<Org>> result = list.stream()
.collect(Collectors.groupingBy(Org::parent_id));
有很多方法可以做到这一点。你也可以试试其他的 你已经说过了,递归的
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)
}
这是你的电话号码。您可以使用forEach
然后使用filter
originalList.forEach(el->{
int parentId = Integer.parseInt(el.get("parent_id").toString());
if(parentId>0) {
List<Map<String, Object>> childList = originalList.stream().filter(e->Integer.parseInt(el.get("id").toString())==parentId).collect(Collectors.toList());
if(!childList.isEmpty()) {
el.put("children",childList );
}
}
});
originalList.forEach(el->{
int parentId=Integer.parseInt(el.get(“parent_id”).toString();
如果(父ID>0){
List childList=originalList.stream().filter(e->Integer.parseInt(el.get(“id”).toString())==parentId.collector(Collectors.toList());
如果(!childList.isEmpty()){
el.put(“儿童”,儿童名单);
}
}
});
您也可以这样做
Map<Long, Org> hashMap = list.stream()
.filter(org -> org.getParent_id!=0)
.collect(Collectors.groupingBy(Org::parent_id));
List<Org> listWithChilds = list.stream()
.filter(org -> org.getParent_id==0)
.map(topOrg -> {
topOrg.addChildren(hashMap.get(topOrg.getId()));
})
.collect(Collectors.toList());
Map hashMap=list.stream()
.filter(org->org.getParent\u id!=0)
.collect(Collectors.groupingBy(Org::parent_id));
List listWithChilds=List.stream()
.filter(org->org.getParent\u id==0)
.map(拓扑->{
topOrg.addChildren(hashMap.get(topOrg.getId());
})
.collect(Collectors.toList());
您是否需要流
来完成此任务?或者,您可以实现更好的数据结构,比如树节点
Map<Long, Org> hashMap = list.stream()
.filter(org -> org.getParent_id!=0)
.collect(Collectors.groupingBy(Org::parent_id));
List<Org> listWithChilds = list.stream()
.filter(org -> org.getParent_id==0)
.map(topOrg -> {
topOrg.addChildren(hashMap.get(topOrg.getId()));
})
.collect(Collectors.toList());