[英]java create multiple tree like structure using parent id from flat file
I have data like below 我有如下数据
CategoryId CategoryName CategoryParentId
123 XYZ 111
111 ABC
222 PQR
555 DEF 111
321 IJK 222
If you see this a unordered data read from a flat file which can be in any order. 如果您看到此消息,则从平面文件读取的无序数据可以是任何顺序。
I want to create trees like below: 我想创建如下树:
111
| \
123 555
and 和
222
\
321
I have this data in an object, which looks like below: 我在一个对象中有此数据,如下所示:
public class Category {
private String id = null;
private String name = null;
private String parentId = null;
public Category(String id, String name, String parentId) {
this.id = id;
this.name = name;
this.parentId = parentId;
}
}
I am trying to process this data to create list of categories tree. 我正在尝试处理此数据以创建类别树列表。
public class CategoryTree {
private String name = null;
private String id = null;
private CategoryTree<String, CategoryTree> children = new TreeMap<String, CategoryTree>();
public CategoryTree() {
}
public CategoryTree(String name, String id) {
setName(name);
setId(id);
}
public TreeMap<String, CategoryTree> getChildren() {
return this.children;
}
public CategoryTree getChild(String childId) {
return this.children.get(childId);
}
public void setChild(CategoryTree child) {
this.children.put(child.getId(), child);
}
public boolean hasChild(String childId) {
TreeMap<String, CategoryTree> set = this.children;
boolean result = set.containsKey(childId);
return result;
}
}
Below is what I am trying to do: 以下是我要执行的操作:
public void processData(List categoryList) {
List<CategoryTree> roleObjectList = new ArrayList<CategoryTree>();
Iterator<Category> itr = categoryList.iterator();
while (itr.hasNext()) {
Category entry = itr.next();
String id = entry.getId();
String name = entry.getName();
String parentId = entry.getParentId();
// i am confused here
// CategoryTree parent = new CategoryTree(name, id);
parent.addChild(entry);
}
}
I am confused on this part. 我对此感到困惑。 How to start the tree.
如何启动树。 Since entry in the first iteration of loop has parent but it's parent is not present in the final list yet.
由于循环的第一次迭代中的条目具有父级,但最终列表中还没有父级。 How to add first entry to it's parent.
如何将第一项添加到其父项。
You can build your tree recursively. 您可以递归地构建树。 First step will be to extract the roots of your trees.
第一步将是提取树木的根。 Then create a function who get the direct children of each node by running on the list (
O(n)
) - inside there will be recursive call for each of the children. 然后创建一个函数,该函数通过在列表(
O(n)
)上运行来获取每个节点的直接子代-内部将为每个子代递归调用。
I guess my JAVA
syntax is little but rusty so this is the pseudo code: 我猜我的
JAVA
语法很少但很生锈,所以这是伪代码:
function getChildren(nodeID, listOfNodes):
childrenList = empty list
for each node in listOfNodes:
if node.parentId == nodeID: // if node is direct child
node.children = getChildren(node.id, listOfNodes); //recursively get all his children
childrenList.add(node) // add it to the children list
return childrenList;
main:
listOfNodes = get list from your file
listOfRoots = init empty list
for each node in listOfNodes:
if (node.parentId is empty) //not parent
listOfRoots.add(node)
// now listOfRoots is has all the roots
for each node in listOfRoots:
node.children = getChildren(node.id, listOfNodes)
This will be in O(n^2)
complexity. 这将是
O(n^2)
复杂度。 2 immediate improvement you can do is save the listOfNode in object and used it as this
so you won't need to overload the memory. 2立即改善你能做的就是保存在对象中的listOfNode,并用它作为
this
,所以你不会需要重载内存。 Second, you can modify the list each time and remove the node that assign (as he cannot be assign twice...) 其次,您可以每次修改列表并删除分配的节点(因为不能两次分配他...)
Hope that helps! 希望有帮助!
It seems that the parent.id < child.id
holds, that is: the parent is created first. 似乎
parent.id < child.id
成立,即:首先创建了父级。 Though not necessary, that condition could sometimes ease things. 尽管不是必需的,但这种情况有时可以缓解问题。
Here it is not needed. 在这里不需要。
public void processData(List<Category> categoryList) {
Map<String, CategoryTree> map = categoryList.collect(
Collectors.toMap(cat -> cat.id,
cat -> new CategoryTree(id, name)));
List<CategoryTree> treeRoots = new ArrayList<>(); // Forrest if more than one root.
categoryList.forEach(cat -> {
CategoryTree node = map.get(cat.id);
if (cat.parentId != null) {
CategoryTree parent = map.get(cat.parentId)
parent.children.add(node );
} else {
treeRoots.add(node );
}
});
List<CategoryTree> roleObjectList = new ArrayList<>(map.values());
...
Though maybe faster than a path following algorithm (that could exploit the id order), it needs additional memory: an extra map. 尽管可能比遵循路径算法(可以利用id顺序)更快,但它需要额外的内存:额外的映射。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.