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

时间:2019-01-17 16:42:11

标签: java tree

我有如下数据

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

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

2 个答案:

答案 0 :(得分:1)

您可以递归地构建树。第一步将是提取树木的根。然后创建一个函数,该函数通过在列表(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保存在object中,并将其用作this,因此您无需使内存过载。其次,您可以每次修改列表并删除分配的节点(因为他不能被分配两次...)

希望有帮助!

答案 1 :(得分:1)

似乎pthread_rwlock_t lock; void handler(void *v) { if ((res = pthread_rwlock_rdlock(&lock)!=0) { exit(1); } printf("I am first! %d\n", v); pthread_rwlock_unlock(&lock); } int main() { pthread_t t[threads]; //First acquire the write lock: if ((res = pthread_rwlock_wrlock(&lock)!=0) { exit(1); } for(int i =0; i < threads; i++) { pthread_create(&t[i], NULL, handler, (void*) i); //it is not clear if you want sleep inside the loop or not // You indented it as if to be inside but not put brackets sleep(2); } pthread_rwlock_unlock(&lock); for(int i =0; i < threads; i++) pthread_join(t[i], NULL); pthread_rwlock_destroy(&lock); return 0; } 成立,即:首先创建了父级。 尽管不是必需的,但这种情况有时可以使事情变得轻松。

这里不需要。

parent.id < child.id

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