如何先打印目录然后打印文件(树)
How can I print the directories first and then the files (tree)
这部分class负责创建目录和文件并追加它。
public class TreeNode<T> implements Iterable<TreeNode<T>> {
public T data;
public TreeNode<T> parent;
public List<TreeNode<T>> children;
public boolean isRoot() {
return parent == null;
}
private List<TreeNode<T>> elementsIndex;
public TreeNode(T data) {
this.data = data;
this.children = new LinkedList<TreeNode<T>>();
this.elementsIndex = new LinkedList<TreeNode<T>>();
this.elementsIndex.add(this);
}
public TreeNode<T> addChild(T child) {
TreeNode<T> childNode = new TreeNode<T>(child);
childNode.parent = this;
this.children.add(childNode);
this.registerChildForSearch(childNode);
return childNode;
}
private void registerChildForSearch(TreeNode<T> node) {
elementsIndex.add(node);
if (parent != null)
parent.registerChildForSearch(node);
}
@Override
public String toString() {
return data != null ? data.toString() : "[data null]";
}
@Override
public Iterator<TreeNode<T>> iterator() {
TreeNode<T> iter = new TreeNode<T>((T) this);
return (Iterator<TreeNode<T>>) iter;
}
public static TreeNode<File> createDirTree(File folder) {
if (!folder.isDirectory()) {
throw new IllegalArgumentException("folder is not a Directory");
}
TreeNode<File> DirRoot = new TreeNode<File>(folder);
for (File file : folder.listFiles()) {
if (file.isDirectory()) {
appendDirTree(file, DirRoot);
} else {
appendFile(file, DirRoot);
}}
return DirRoot;
}
public static void appendDirTree(File folder, TreeNode<File> DirRoot) {
DirRoot.addChild(folder);
for (File file : folder.listFiles()) {
if (file.isDirectory()) {
appendDirTree(file, DirRoot.children.get(DirRoot.children.size() - 1));
} else {
appendFile(file, DirRoot.children.get(DirRoot.children.size() - 1));
}} }
public static void appendFile(File file, TreeNode<File> filenode) {
filenode.addChild(file);
}
问题是在这种代码状态下,文件和目录打印如下:
rootFolder
├─ Folder1
│ ├─ subFolder1
│ │ ├─ a.txt
│ │ ├─ b.txt
│ │ ├─ c.txt
│ │ └─ d.txt
│ ├─ subFolder2
│ │ ├─ a.txt
│ │ ├─ B.txt
│ │ ├─ c.txt
│ │ └─ D.txt
│ ├─ subFolder3
│ │ ├─ A.txt
│ │ ├─ b.txt
│ │ ├─ C.txt
│ │ └─ d.txt
│ └─ subFolder4
│ ├─ a.txt
│ ├─ b.txt
│ ├─ c.txt
│ └─ d.txt
├─ File1.txt
├─ Folder2
│ ├─ a.txt
│ ├─ b.txt
│ ├─ c.txt
│ └─ d.txt
└─ File2.txt
但我需要目录先行,然后是文件:File1.txt
靠近 File2.txt
。我试图找出问题出在哪里,但无济于事。我需要更改什么以及代码中的何处才能获得所需的结果?
问题在于您附加子树的顺序。
正如 Java Documentation 所说 .listFiles()
:
There is no guarantee that the name strings in the resulting array will appear in any specific order; they are not, in particular, guaranteed to appear in alphabetical order.
因此您需要在附加文件之前对文件进行排序。
这里是方法 createDirTree
和 appendDirTree
的可能解决方案。
(注:排序只根据if its a directory or not. If you need another custom sorting, you need to adapt the
Comparator`)
public static TreeNode<File> createDirTree(File folder) {
if (!folder.isDirectory()) {
throw new IllegalArgumentException("folder is not a Directory");
}
List<File> children = Arrays.asList(folder.listFiles());
children.sort(Comparator.comparing(file -> file.isDirectory() ? -1 : 1));
TreeNode<File> DirRoot = new TreeNode<File>(folder);
for (File file : children) {
if (file.isDirectory()) {
appendDirTree(file, DirRoot);
} else {
appendFile(file, DirRoot);
}}
return DirRoot;
}
public static void appendDirTree(File folder, TreeNode<File> dirRoot) {
dirRoot.addChild(folder);
List<File> children = Arrays.asList(folder.listFiles());
children.sort(Comparator.comparing(file -> file.isDirectory() ? -1 : 1));
for (File file : children) {
if (file.isDirectory()) {
appendDirTree(file, dirRoot.children.get(dirRoot.children.size() - 1));
} else {
appendFile(file, dirRoot.children.get(dirRoot.children.size() - 1));
}
}
}
有几种方法可以实现这一点。例如。你也可以使用流。请参阅下面 createDirTree
的示例:
public static TreeNode<File> createDirTree(File folder) {
if (!folder.isDirectory()) {
throw new IllegalArgumentException("folder is not a Directory");
}
TreeNode<File> DirRoot = new TreeNode<File>(folder);
Arrays.stream(folder.listFiles())
.sorted(Comparator.comparing(f -> (f.isDirectory() ? 1 : -1)))
.forEach(file -> {
if (file.isDirectory()) {
appendDirTree(file, DirRoot);
} else {
appendFile(file, DirRoot);
}
});
return DirRoot;
}
这部分class负责创建目录和文件并追加它。
public class TreeNode<T> implements Iterable<TreeNode<T>> {
public T data;
public TreeNode<T> parent;
public List<TreeNode<T>> children;
public boolean isRoot() {
return parent == null;
}
private List<TreeNode<T>> elementsIndex;
public TreeNode(T data) {
this.data = data;
this.children = new LinkedList<TreeNode<T>>();
this.elementsIndex = new LinkedList<TreeNode<T>>();
this.elementsIndex.add(this);
}
public TreeNode<T> addChild(T child) {
TreeNode<T> childNode = new TreeNode<T>(child);
childNode.parent = this;
this.children.add(childNode);
this.registerChildForSearch(childNode);
return childNode;
}
private void registerChildForSearch(TreeNode<T> node) {
elementsIndex.add(node);
if (parent != null)
parent.registerChildForSearch(node);
}
@Override
public String toString() {
return data != null ? data.toString() : "[data null]";
}
@Override
public Iterator<TreeNode<T>> iterator() {
TreeNode<T> iter = new TreeNode<T>((T) this);
return (Iterator<TreeNode<T>>) iter;
}
public static TreeNode<File> createDirTree(File folder) {
if (!folder.isDirectory()) {
throw new IllegalArgumentException("folder is not a Directory");
}
TreeNode<File> DirRoot = new TreeNode<File>(folder);
for (File file : folder.listFiles()) {
if (file.isDirectory()) {
appendDirTree(file, DirRoot);
} else {
appendFile(file, DirRoot);
}}
return DirRoot;
}
public static void appendDirTree(File folder, TreeNode<File> DirRoot) {
DirRoot.addChild(folder);
for (File file : folder.listFiles()) {
if (file.isDirectory()) {
appendDirTree(file, DirRoot.children.get(DirRoot.children.size() - 1));
} else {
appendFile(file, DirRoot.children.get(DirRoot.children.size() - 1));
}} }
public static void appendFile(File file, TreeNode<File> filenode) {
filenode.addChild(file);
}
问题是在这种代码状态下,文件和目录打印如下:
rootFolder
├─ Folder1
│ ├─ subFolder1
│ │ ├─ a.txt
│ │ ├─ b.txt
│ │ ├─ c.txt
│ │ └─ d.txt
│ ├─ subFolder2
│ │ ├─ a.txt
│ │ ├─ B.txt
│ │ ├─ c.txt
│ │ └─ D.txt
│ ├─ subFolder3
│ │ ├─ A.txt
│ │ ├─ b.txt
│ │ ├─ C.txt
│ │ └─ d.txt
│ └─ subFolder4
│ ├─ a.txt
│ ├─ b.txt
│ ├─ c.txt
│ └─ d.txt
├─ File1.txt
├─ Folder2
│ ├─ a.txt
│ ├─ b.txt
│ ├─ c.txt
│ └─ d.txt
└─ File2.txt
但我需要目录先行,然后是文件:File1.txt
靠近 File2.txt
。我试图找出问题出在哪里,但无济于事。我需要更改什么以及代码中的何处才能获得所需的结果?
问题在于您附加子树的顺序。
正如 Java Documentation 所说 .listFiles()
:
There is no guarantee that the name strings in the resulting array will appear in any specific order; they are not, in particular, guaranteed to appear in alphabetical order.
因此您需要在附加文件之前对文件进行排序。
这里是方法 createDirTree
和 appendDirTree
的可能解决方案。
(注:排序只根据if its a directory or not. If you need another custom sorting, you need to adapt the
Comparator`)
public static TreeNode<File> createDirTree(File folder) {
if (!folder.isDirectory()) {
throw new IllegalArgumentException("folder is not a Directory");
}
List<File> children = Arrays.asList(folder.listFiles());
children.sort(Comparator.comparing(file -> file.isDirectory() ? -1 : 1));
TreeNode<File> DirRoot = new TreeNode<File>(folder);
for (File file : children) {
if (file.isDirectory()) {
appendDirTree(file, DirRoot);
} else {
appendFile(file, DirRoot);
}}
return DirRoot;
}
public static void appendDirTree(File folder, TreeNode<File> dirRoot) {
dirRoot.addChild(folder);
List<File> children = Arrays.asList(folder.listFiles());
children.sort(Comparator.comparing(file -> file.isDirectory() ? -1 : 1));
for (File file : children) {
if (file.isDirectory()) {
appendDirTree(file, dirRoot.children.get(dirRoot.children.size() - 1));
} else {
appendFile(file, dirRoot.children.get(dirRoot.children.size() - 1));
}
}
}
有几种方法可以实现这一点。例如。你也可以使用流。请参阅下面 createDirTree
的示例:
public static TreeNode<File> createDirTree(File folder) {
if (!folder.isDirectory()) {
throw new IllegalArgumentException("folder is not a Directory");
}
TreeNode<File> DirRoot = new TreeNode<File>(folder);
Arrays.stream(folder.listFiles())
.sorted(Comparator.comparing(f -> (f.isDirectory() ? 1 : -1)))
.forEach(file -> {
if (file.isDirectory()) {
appendDirTree(file, DirRoot);
} else {
appendFile(file, DirRoot);
}
});
return DirRoot;
}