我有一个列表,其中包含由相同类型(类)表示的所有父项和子项。我想从平面列表中生成分层列表。
以下是我的班级,代表父母和孩子。在这里,我需要根据 parentId 为父级映射子项。根级别(无父级)以parentId 0 开始。
import java.util.ArrayList;
import java.util.List;
class Customers {
private int id;
private String name;
private int parentId;
private List<Customers> childs;
public Customers(int id, String name, int parentId) {
this(id, name, parentId, null);
}
public Customers(int id, String name, int parentId, List<Customers> childs) {
this.id = id;
this.name = name;
this.parentId = parentId;
this.childs = childs;
}
}
public class Application {
public static void main(String[] args) {
//Input List
Customers customer = new Customers(1, "Hel", 0);
Customers customerChild1 = new Customers(2, "Hel-Child1", 1);
Customers customerChild2 = new Customers(5, "Hel-Child2", 1);
Customers customerInnerChild1 = new Customers(3, "Hel-InnerChild1", 2);
Customers customerInnerChild2 = new Customers(4, "Hel-InnerChild2", 2);
List<Customers> customers = new ArrayList();
customers.add(customerInnerChild1);
customers.add(customerInnerChild2);
customers.add(customer);
customers.add(customerChild1);
customers.add(customerChild2);
}
public static List<Customers> hierarchicalList(List<Customers> Customers) {
return null;
}
}
我会将List<Customer>
作为输入传递给某个方法。该方法应该返回List<Customer>
父母和子女关系。
我需要帮助以优化的方式建立父子关系。
输入:
[
{
"id": 1,
"name": "Hel",
"parentId": 0
},
{
"id": 5,
"name": "Hel-Child2",
"parentId": 1
},
{
"id": 4,
"name": "Hel-InnerChild2",
"parentId": 2
},
{
"id": 3,
"name": "Hel-InnerChild1",
"parentId": 2
},
{
"id": 2,
"name": "Hel-Child1",
"parentId": 1
}
]
期待输出:
[
{
"id": 1,
"name": "Hel",
"parentId": 0,
"childs": [
{
"id": 2,
"name": "Hel-Child1",
"parentId": 1,
"childs": [
{
"id": 3,
"name": "Hel-InnerChild1",
"parentId": 2
}, {
"id": 4,
"name": "Hel-InnerChild2",
"parentId": 2
}
]
}, {
"id": 5,
"name": "Hel-Child2",
"parentId": 1
}
]
}
]
注意:输入列表未排序。
答案 0 :(得分:1)
如果您只需要检查每个孩子的父母是谁,您只需要过滤列表并为每个元素设置子项。像这样:
public List<Customer> getHierarchicalList(final List<Customer> originalList) {
final List<Customer> copyList = new ArrayList<>(originalList);
copyList.forEach(element -> {
originalList
.stream()
.filter(parent -> parent.id == element.parentId)
.findAny()
.ifPresent(parent -> {
if (parent.childs == null) {
parent.childs = new ArrayList<>();
}
parent.childs.add(element);
originalList.remove(element);
});
});
return originalList;
}
答案 1 :(得分:0)
这个类已经是分层的。
如果您打印父项,然后递归打印子项,您将看到一棵树。
您期望发生什么?
这只是一个关于如何迭代树的问题:深度优先还是广度?
关于从平面列表到树的问题是关于解析平面列表的问题。你如何区分公寓中的父母和孩子?这应该会给你一个如何进行的暗示。
您需要一个工厂类,它接受一个Customer of List,解析List,并返回Customer的根实例及其子项在适当的树结构中。
答案 2 :(得分:0)
我想扩展阮的答案,
通过使用Rhuan的代码,您将获得所有节点都位于根级别上的信息,只有一个具有正确内容和顺序的节点,通过删除错误的内容,您将获得更好的结果:
public List<Customer> getHierarchicalList(final List<Customer> originalList) {
final List<Customer> copyList = new ArrayList<>(originalList);
copyList.forEach(element -> {
originalList
.stream()
.filter(parent -> parent.id == element.parentId)
.findAny()
.ifPresent(parent -> {
if (parent.childs == null) {
parent.childs = new ArrayList<>();
}
parent.childs.add(element);
/* originalList.remove(element); don't remove the content before completing the recursive */
});
});
originalList.subList(1, originalList.size()).clear();
return originalList;
}
清除有关subList的注释。
答案 3 :(得分:0)
我也想扩展一下阮的回答。
如果他的代码导致无限循环,则需要比较父元素和元素 id,它们不应该等于 parent.id != element.id
。
所以你的代码将是:
public List<Customer> getHierarchicalList(final List<Customer> originalList) {
final List<Customer> copyList = new ArrayList<>(originalList);
copyList.forEach(element -> {
originalList
.stream()
.filter(parent -> parent.id == element.parentId && parent.id != element.id)
.findAny()
.ifPresent(parent -> {
if (parent.childs == null) {
parent.childs = new ArrayList<>();
}
parent.childs.add(element);
originalList.remove(element);
});
});
return originalList;
}