0

I'm facing the following issue and I've been racking my brain looking for a solution, but nothing comes to my mind by now:

I have a file system hierarchy, something like:

/HANDLERS/HANDLER1
/HANDLERS/HANDLER2
/HANDLERS/HANDLER3

and

/MODULES/PROGRAMMING/PROGRAMMER1
/MODULES/PROGRAMMING/PROGRAMMER2
/MODULES/PROGRAMMING/PROGRAMMER3

/MODULES/TESTING/TESTING1
/MODULES/TESTING/TESTING2

and so on.

I want to create a "tree" assuming "/" which is the root is already created. And the structure shown in the image I attach is the goal.

enter image description here

I need a method called

void createNode(String path){

}

In my requirements, this method will always receive the full path and do something like the following:

void create(String fullPath){
 //Here I use a method which splits the fullPath into a String array to get every part that will represent a node, for example, if the fullPath is /MODULE/PROGRAMMING/PROHRAMMER1 I use:
String[] singleNodes = separateNodes(fullPath);//I get:MODULE,PROGRAMMING AND PROGRAMMER
//Then I use a loop to iterate the elements

for (String s : singleNodes) {
}
//WHAT CAN I DO HERE?
}

But I don't have idea on how to work inside the loop, I need to check if the node exists, if it exists, I just have to add the missing part, for instance, if I send /MODULES/PROGRAMMING/PROGRAMMER1, if I send for the very first time, it will create the whole thing, but if then I send /MODULES/PROGRAMMING/PROGRAMMER2, it just have to add PROGRAMMER2.

If somebody could help me I will really appretiate it, thanks in advance.

4

4 回答 4

1

免责声明:未经测试,没有错误检查,没有 getter/setter。

package com.jorge.teste;

import java.util.ArrayList;
import java.util.List;

public class Main {

    public static class Tree<T> {
        Node<T> root;

        public static class Node<T> {
            T data;

            Node<T> parent;

            List<Node<T>> children = new ArrayList<Main.Tree.Node<T>>();

            public Node(final T data, final Node<T> parent) {
                this.data = data;
                this.parent = parent;
            }
        }
    }

    public static Tree<String> tree = new Tree<String>();

    public static void createNode(final String path) {
        String[] parts = path.split("/");
        Tree.Node<String> parent = null;
        for (String part : parts) {
            if (parent == null) {
                if (tree.root == null) {
                    tree.root = new Tree.Node<String>(part, null);
                }
                parent = tree.root;
            } else {
                Tree.Node<String> found = null;
                for (Tree.Node<String> child : parent.children) {
                    if (child.data.equals(part)) {
                        found = child;
                        break;
                    }
                }

                if (found == null) {
                    parent.children.add(found = new Tree.Node<String>(part, parent));
                }

                parent = found;
            }
        }
    }

    public static void main(final String[] args) {
        createNode("/a/b/c");
        createNode("/a/b/c/d");
    }
}
于 2013-04-24T14:53:48.257 回答
1

如何在 Java 中将文件路径转换为层次结构

Node createNode(String path) {
    File location = new File(path);
    File[] children = file.listFiles();
    Node node = new Node(location.getName());

    if(location.isDirectory()) {
        List<Node> children = new ArrayList();
        for(File child : children) {
            children.add(createNode(child.getPath()));
        }
        node.setChildren(children);
    }
    return node;
}

class Node {
    String name;
    List<Node> children;
}

你可以这样称呼createNode(myRoot)

于 2013-04-24T14:38:13.947 回答
0

我终于设法做到了,它符合我的要求,这与我向 zookeeper 提出的问题有关。

此致。

public void createNode(NodePath nodePath, NodeData nodeData, NodeRights nodeRights, NodeCreationHandler nodeCreationHandler) throws KeeperException, InterruptedException, ZookeeperCreationException {

        if (zk == null) {
            throw new ZookeeperCreationException("The zookeeper client has not been instanced.");
        }       
        String targetPath = nodePath.getFullNodePath();
        logger.warn("full path: " + targetPath);
        targetPath = targetPath.substring(1, targetPath.length());
        logger.warn("full path mod: " + targetPath);
        byte[] serializedData = nodeData.serialize(new Object());
        String[] array = targetPath.split(ICoordinationConstants.BASE_ROOT_SPTR);
        String acum="";
        for (int i = 0; i < array.length-1; i++) {
            acum+=(ICoordinationConstants.BASE_ROOT_SPTR+array[i]);
            logger.warn("acum: " + acum);
            if (zk.exists(acum, null) == null) {
                logger.warn("It does not exists, proceed to create it...");
                zk.create(acum, serializedData, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            }
        }
        zk.create(acum+ICoordinationConstants.BASE_ROOT_SPTR+array[array.length-1], serializedData, Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);             
    }
于 2013-04-25T18:16:21.880 回答
0

如果你想坚持你目前的循环,那么你应该尝试这样的事情(我假设你已经有了上面所说的根节点)

Node currentNode = rootNode; 
for (String s : singleNodes) {
     if( currentNode.hasChild(s) ) currentNode = currentNode.getChild(s);
     else currentNode = currentNode.createChild(s);
}

在这里假设 createChild(s) 返回创建的节点,这可能不应该。但这不是真正的问题

但老实说,我认为这不应该使用循环来完成,通常使用递归更好地处理树。

于 2013-04-24T14:48:54.663 回答