簡體   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