このようなパスのリストがあります
/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の「仮想的な」表現を可能にする構造でした。
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();
}
}
改善についての良いアドバイスがあれば教えてください:)
私は自分自身で課題への解決策を実装しました、それは GitHubGistとして利用可能 です。
DirectoryNodeのファイルシステム階層の各ノードを表しています。ヘルパーメソッドcreateDirectoryTree(String [] filesystemList)はディレクトリツリーを作成します。
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=[]}]}]}
Trie / Radix Trie または Binary Search Tree をどちらの状況でも機能するように変更できるようです。 (通常のTrieのような文字の代わりに)Trieを拡張して「フォルダ」を内部ノードとして格納するか、またはバイナリサーチツリーを拡張して「フォルダ」を内部ノードとして格納することができます(同等のインターフェースを実装している場合)。リーフノードとしての「ファイル」。
これらの構造の私の実装は、上のテキストにリンクされています。