我有像这样的路径列表
/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
所以从路径(蜇伤)这个名单,我需要克里特岛有文件夹,节点和文件作为叶(也不会是空文件夹叶)一个Java树结构。
我需要的,我认为是add方法,我传递给他们一个字符串(文件的路径),它是在树中创建正确的节点(文件夹),如果他们尚不存在添加到正确的地方
这种树形结构需要我获得节点列表,当我在节点和叶子的名单(但我认为这将是树木正常功能)
我会永远字符串作为路径,而不是真正的文件或文件夹。 有什么准备使用或源代码开始?
非常感谢你。
感谢您对所有的答案。 我做了我工作的落实。 我想,我需要改进,以使其工作在添加元素的树结构有更多的缓存更好。
就像我说的什么,我需要的是,让我有一个FS的“虚拟” rappresentation的结构。
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<MXMNode> childs;
List<MXMNode> leafs;
String data;
String incrementalPath;
public MXMNode( String nodeValue, String incrementalPath ) {
childs = new ArrayList<MXMNode>();
leafs = new ArrayList<MXMNode>();
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();
}
}
请告诉我,如果你有关于改进措施一些好的建议:)
好像你可以适应无论是特里 / 板蓝根特里或二叉搜索树在任何一种情况下工作。 你可以增加一个特里存储“文件夹”作为内部节点(而不是像在常规特里字符),或者你可以增加一个二叉搜索树来存储“文件夹”作为内部节点(只要它们实现可比接口)和“文件”叶节点。
我的这些结构的实施上面的文字链接。
我建议在阅读了数据结构 ,尤其是树木 。 在Java中,你可以通过创建具有其他节点引用一个节点类代表这些。 例如:
public class Node {
private Node[] children;
/* snip other fields */
public boolean isFile() {
return children.count == 0;
}
}
很明显,你可以反正你喜欢 - 数组或集合存储您的节点的引用将与非二进制树工作。
鉴于您的文件列表,你可以阅读这些并填充树结构。
我实现了一个解决方案来挑战自己,它可以作为一个GitHubGist 。
我代表在DirectoryNode文件系统的层次结构中的每个节点。 一个helper-方法createDirectoryTree(字符串[]使用FileSystemList)创建了一个direcotry树。
这里是使用示例中,它包括在所述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);
该-output 的System.out.println是:
{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包 。 所有你需要的是内在的。