List转树,寻找树的所有叶子路径
作者:互联网
需求
最近公司有一个需求,总结下来就是一个扁平List转成树,然后获取到树的所有路径。
下面是需求抽象出的部分实体类和部分字段
@Data
public class FormTopic {
private Integer topicId;//当前节点id
private Integer parentId;//父id
private String topicName;//节点名
private List<FormTopic> children;//所有子节点
public FormTopic(Integer topicId, Integer parentId, String topicName) {
this.topicId = topicId;
this.parentId = parentId;
this.topicName = topicName;
}
}
/**
* 模拟DAO层从数据库查到的数据
*/
private static List<FormTopic> getFormTopics(){
List<FormTopic> topics = new ArrayList<>();
FormTopic formTopic = new FormTopic(1,-1,"A");
FormTopic formTopic2 = new FormTopic(2,-1,"B");
FormTopic formTopic3 = new FormTopic(3,1,"C");
FormTopic formTopic4 = new FormTopic(4,1,"D");
FormTopic formTopic5 = new FormTopic(5,3,"E");
FormTopic formTopic6 = new FormTopic(6,5,"F");
FormTopic formTopic7 = new FormTopic(7,2,"G");
FormTopic formTopic8 = new FormTopic(8,2,"H");
FormTopic formTopic9 = new FormTopic(9,7,"I");
FormTopic formTopic10 = new FormTopic(10,3,"J");
FormTopic formTopic11 = new FormTopic(11,2,"K");
topics.add(formTopic);
topics.add(formTopic2);
topics.add(formTopic3);
topics.add(formTopic4);
topics.add(formTopic5);
topics.add(formTopic6);
topics.add(formTopic7);
topics.add(formTopic8);
topics.add(formTopic9);
topics.add(formTopic10);
topics.add(formTopic11);
return topics;
}
如图所示:
下面用java实现:
public static void main(String[] args) {
List<FormTopic> formTopics = getFormTopics();
List<FormTopic> trees = convertToTree(formTopics);
List<LinkedList<FormTopic>> allPath = depthFirstTraversal(trees);
System.out.println("============");
}
/**
* 删除冗余树节点
*/
private static void clearSurplusNode(List<LinkedList<FormTopic>> allPath) {
Set<Integer> set = new HashSet<>();
for(List<FormTopic> topics : allPath){
for (FormTopic topic : topics) {
if(!set.contains(topic.getTopicId()) && topic.getChildren()!=null){
topic.setChildren(null);
set.add(topic.getTopicId());
}
}
}
}
/**
*递归形式的深度优先遍历
*/
private static List<LinkedList<FormTopic>> depthFirstTraversal(List<FormTopic> trees) {
List<LinkedList<FormTopic>> result = new ArrayList<>();
for(FormTopic tree : trees){
LinkedList<FormTopic> path = new LinkedList<>();
path.add(tree);
findPath(result, tree, path);
}
clearSurplusNode(result);
return result;
}
private static void findPath(List<LinkedList<FormTopic>> result, FormTopic tree, LinkedList<FormTopic> path) {
List<FormTopic> children = tree.getChildren();
if (children == null || children.size() <= 0) {
result.add(path);
return;
}
for (FormTopic child : children) {
LinkedList<FormTopic> cPath = new LinkedList<>(path);
cPath.add(child);
findPath(result, child, cPath);
}
}
private static List<FormTopic> convertToTree(List<FormTopic> formTopics) {
List<FormTopic> roots = formTopics.stream().filter(t -> t.getParentId() == -1).collect(Collectors.toList());
return toTree(roots, formTopics);
}
//转成树
private static List<FormTopic> toTree(List<FormTopic> roots, List<FormTopic> formTopics) {
return roots.stream().peek(topic -> {
List<FormTopic> children = formTopics.stream().filter(t -> topic.getTopicId().equals(t.getParentId())).collect(Collectors.toList());
toTree(children, formTopics);
topic.setChildren(children);
}).collect(Collectors.toList());
}
断点:
以上代码就实现了上述需求(可能非最优解,勿喷)
标签:FormTopic,topics,路径,List,private,add,转树,new 来源: https://www.cnblogs.com/wwjj4811/p/14238419.html