Java Tree用于表示路径列表中的文件系统(files / dir)

我有这样的路径列表

/mnt/sdcard/folder1/a/b/file1 /mnt/sdcard/folder1/a/b/file2 /mnt/sdcard/folder1/a/b/file3 /mnt/sdcard/folder1/a/b/file4 /mnt/sdcard/folder1/a/b/file5 /mnt/sdcard/folder1/e/c/file6 /mnt/sdcard/folder2/d/file7 /mnt/sdcard/folder2/d/file8 /mnt/sdcard/file9 

因此,从这个路径列表(Stings)我需要创建一个Java Tree结构,其中包含文件夹作为节点,文件作为leaf(不会将空文件夹作为叶子)。

我需要的是我想的是add方法,我向它们传递一个String(文件的路径),然后将它添加到树中的正确位置,如果它们不在那里,则创建正确的节点(Folder)

当我在节点和叶子列表上时,这个树结构将需要我获取节点列表(但我认为这将是树的常规function)

我将始终将字符串作为路径而不是真正的文件或文件夹。 是否有可以使用的东西或源代码开始?

非常感谢你。

谢谢你的所有答案。 我做了我的工作实施。 我认为我需要对其进行改进,以便在向树结构添加元素时使用更多缓存来使其更好地工作。

正如我所说的那样,我需要的是一种允许我对FS进行“虚拟”描述的结构。

MXMTree.java

 public class MXMTree { MXMNode root; MXMNode commonRoot; public MXMTree( MXMNode root ) { this.root = root; commonRoot = null; } public void addElement( String elementValue ) { String[] list = elementValue.split("/"); // latest element of the list is the filename.extrension root.addElement(root.incrementalPath, list); } public void printTree() { //I move the tree common root to the current common root because I don't mind about initial folder //that has only 1 child (and no leaf) getCommonRoot(); commonRoot.printNode(0); } public MXMNode getCommonRoot() { if ( commonRoot != null) return commonRoot; else { MXMNode current = root; while ( current.leafs.size() <= 0 ) { current = current.childs.get(0); } commonRoot = current; return commonRoot; } } } 

MXMNode.java

 import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class MXMNode { List childs; List leafs; String data; String incrementalPath; public MXMNode( String nodeValue, String incrementalPath ) { childs = new ArrayList(); leafs = new ArrayList(); data = nodeValue; this. incrementalPath = incrementalPath; } public boolean isLeaf() { return childs.isEmpty() && leafs.isEmpty(); } public void addElement(String currentPath, String[] list) { //Avoid first element that can be an empty string if you split a string that has a starting slash as /sd/card/ while( list[0] == null || list[0].equals("") ) list = Arrays.copyOfRange(list, 1, list.length); MXMNode currentChild = new MXMNode(list[0], currentPath+"/"+list[0]); if ( list.length == 1 ) { leafs.add( currentChild ); return; } else { int index = childs.indexOf( currentChild ); if ( index == -1 ) { childs.add( currentChild ); currentChild.addElement(currentChild.incrementalPath, Arrays.copyOfRange(list, 1, list.length)); } else { MXMNode nextChild = childs.get(index); nextChild.addElement(currentChild.incrementalPath, Arrays.copyOfRange(list, 1, list.length)); } } } @Override public boolean equals(Object obj) { MXMNode cmpObj = (MXMNode)obj; return incrementalPath.equals( cmpObj.incrementalPath ) && data.equals( cmpObj.data ); } public void printNode( int increment ) { for (int i = 0; i < increment; i++) { System.out.print(" "); } System.out.println(incrementalPath + (isLeaf() ? " -> " + data : "") ); for( MXMNode n: childs) n.printNode(increment+2); for( MXMNode n: leafs) n.printNode(increment+2); } @Override public String toString() { return data; } } 

Test.java用于测试代码

 public class Test { /** * @param args */ public static void main(String[] args) { String slist[] = new String[] { "/mnt/sdcard/folder1/a/b/file1.file", "/mnt/sdcard/folder1/a/b/file2.file", "/mnt/sdcard/folder1/a/b/file3.file", "/mnt/sdcard/folder1/a/b/file4.file", "/mnt/sdcard/folder1/a/b/file5.file", "/mnt/sdcard/folder1/e/c/file6.file", "/mnt/sdcard/folder2/d/file7.file", "/mnt/sdcard/folder2/d/file8.file", "/mnt/sdcard/file9.file" }; MXMTree tree = new MXMTree(new MXMNode("root", "root")); for (String data : slist) { tree.addElement(data); } tree.printTree(); } } 

请告诉我你是否对改进有一些好的建议:)

似乎您可以调整Trie / Radix Trie或二叉搜索树以适应任何一种情况。 你可以增加Trie来存储“文件夹”作为内部节点(而不是常规Trie中的字符),或者你可以扩充二进制搜索树以将“文件夹”存储为内部节点(只要它们实现了类似的界面)和“文件”作为叶节点。

我在上文中将这些结构的实施联系起来。

我建议阅读数据结构 ,特别是树木 。 在Java中,您可以通过创建具有对其他节点的引用的节点类来表示这些。 例如:

 public class Node { private Node[] children; /* snip other fields */ public boolean isFile() { return children.count == 0; } } 

显然,您可以随意存储节点引用 – 数组或集合将与非二叉树一起使用。

根据您的文件列表,您可以阅读这些文件并填充您的树结构。

我自己实施了挑战解决方案,它可以作为GitHubGist使用 。

我代表DirectoryNode中文件系统层次结构的每个节点。 辅助方法createDirectoryTree(String [] filesystemList)创建一个direcotry-tree。

以下是GitHubGist中包含的用法示例。

 final String[] list = new String[]{ "/mnt/sdcard/folder1/a/b/file1.file", "/mnt/sdcard/folder1/a/b/file2.file", "/mnt/sdcard/folder1/a/b/file3.file", "/mnt/sdcard/folder1/a/b/file4.file", "/mnt/sdcard/folder1/a/b/file5.file", "/mnt/sdcard/folder1/e/c/file6.file", "/mnt/sdcard/folder2/d/file7.file", "/mnt/sdcard/folder2/d/file8.file", "/mnt/sdcard/file9.file" }; final DirectoryNode directoryRootNode = createDirectoryTree(list); System.out.println(directoryRootNode); 

System.out.println -output是:

  {value='mnt', children=[{value='sdcard', children=[{value='folder1', children=[{value='a', children=[{value='b', children=[{value='file1.file', children=[]}, {value='file2.file', children=[]}, {value='file3.file', children=[]}, {value='file4.file', children=[]}, {value='file5.file', children=[]}]}]}, {value='e', children=[{value='c', children=[{value='file6.file', children=[]}]}]}]}, {value='folder2', children=[{value='d', children=[{value='file7.file', children=[]}, {value='file8.file', children=[]}]}]}, {value='file9.file', children=[]}]}]} 

看看新的Java 7 – nio2包 。 你只需要在里面。