繁体   English   中英

Java使用平面文件中的父ID创建多个类似树的结构

[英]java create multiple tree like structure using parent id from flat file

我有如下数据

CategoryId  CategoryName  CategoryParentId
123         XYZ           111
111         ABC           
222         PQR           
555         DEF           111
321         IJK           222

如果您看到此消息,则从平面文件读取的无序数据可以是任何顺序。

我想创建如下树:

111
|  \
123 555  

222
\
321

我在一个对象中有此数据,如下所示:

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;
    }
}

我正在尝试处理此数据以创建类别树列表。

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;
    }
}

以下是我要执行的操作:

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);
    }
}

我对此感到困惑。 如何启动树。 由于循环的第一次迭代中的条目具有父级,但最终列表中还没有父级。 如何将第一项添加到其父项。

您可以递归地构建树。 第一步将是提取树木的根。 然后创建一个函数,该函数通过在列表( O(n) )上运行来获取每个节点的直接子代-内部将为每个子代递归调用。

我猜我的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)

这将是O(n^2)复杂度。 2立即改善你能做的就是保存在对象中的listOfNode,并用它作为this ,所以你不会需要重载内存。 其次,您可以每次修改列表并删除分配的节点(因为不能两次分配他...)

希望有帮助!

似乎parent.id < child.id成立,即:首先创建了父级。 尽管不是必需的,但这种情况有时可以缓解问题。

在这里不需要。

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());
    ...

尽管可能比遵循路径算法(可以利用id顺序)更快,但它需要额外的内存:额外的映射。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM