21

私はこのようなパスのリストを持っています

/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ツリー構造を作成する必要があります(リーフとして空のフォルダーはありません)。

私が必要だと思うのは、文字列(ファイルのパス)をそれらに渡し、ツリー内の正しい場所に追加して、正しいノード(フォルダー)がまだ存在しない場合はそれを作成するaddメソッドです。

このツリー構造では、ノードにいるときにノードのリストとリーフのリストを取得する必要があります(ただし、これはツリーの通常の機能になると思います)

私は常に文字列をパスとして使用し、実際のファイルやフォルダーは使用しません。使用する準備ができているものや、開始するためのソースコードはありますか?

どうもありがとうございます。

4

5 に答える 5

24

ご回答ありがとうございます。私は自分の実用的な実装を行いました。ツリー構造に要素を追加する際に、より多くのキャッシュを使用してより適切に機能させるには、これを改善する必要があると思います。

私が必要としていたのは、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();
    }

}

改善について何か良いアドバイスがあれば教えてください:)

于 2012-06-07T15:38:00.713 に答える
3

私は自分で課題の解決策を実装しました。それは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=[]}]}]}
于 2017-12-07T09:11:27.843 に答える
2

Trie / RadixTrieまたはBinarySearchTreeのいずれかをどちらの状況でも機能するように適合させることができるようです。Trieを拡張して(通常のTrieのような文字ではなく)内部ノードとして「フォルダー」を格納するか、バイナリ検索ツリーを拡張して「フォルダー」を内部ノードとして格納することができます(同等のインターフェイスを実装している場合)。リーフノードとしての「ファイル」。

これらの構造の私の実装は、上記のテキストにリンクされています。

于 2012-06-07T13:22:02.523 に答える
1

データ構造、特にツリーを読むことをお勧めします。Javaでは、他のノードへの参照を持つノードクラスを作成することで、これらを表すことができます。例えば:

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

もちろん、ノード参照は好きなように保存できます。配列またはコレクションは非バイナリツリーで機能します。

ファイルのリストがあれば、これらを読み取ってツリー構造にデータを入力できます。

于 2012-06-07T13:14:23.613 に答える
-1

新しいJava7-nio2パッケージをご覧ください。必要なのは中にあります。

于 2012-06-07T13:09:12.500 に答える