比较<文件>对于“目录优先”订购 [英] Comparator<File> for "directories-first" order
问题描述
我很难过...假设我有这个目录树:
I'm stumped... Let's say I have this directory tree:
{someRoot}/
{someRoot}/bar/
{someRoot}/bar/file1.txt
{someRoot}/foo/
{someRoot}/foo/baz/
{someRoot}/foo/baz/file3.txt
{someRoot}/foo/abracadabra.txt
{someRoot}/foo/file2.txt
{someRoot}/aardvark.txt
{someRoot}/food.txt
{someRoot}/zebra.txt
您会注意到订购。将此 order1 称为。在每个阶段,目录首先出现在文件之前。 (注意: bar / file1.txt
在 foo
之前,所以在全球范围内,目录并非都在所有文件之前。)
You'll note the ordering. Call this order1. At each stage, the directories come first before the files. (NOTE: bar/file1.txt
comes before foo
, so on a global basis, the directories do not all come before all the files.)
如果我枚举这个目录树,然后递归枚举子目录,我将得到以下列表<文件>
,订购 order2 。
If I enumerate this directory tree, and then recursively enumerate the subdirectories, I'll get the following List<File>
, with ordering order2.
{someRoot}/
{someRoot}/aardvark.txt
{someRoot}/bar/
{someRoot}/foo/
{someRoot}/food.txt
{someRoot}/zebra.txt
{someRoot}/bar/file1.txt
{someRoot}/foo/abracadabra.txt
{someRoot}/foo/baz/
{someRoot}/foo/file2.txt
{someRoot}/foo/baz/file3.txt
如果我创建直截了当的比较器<文件>
:
If I create the straightforward Comparator<File>
:
Comparator<File> fc = new Comparator<File>(){
@Override public int compare(File o1, File o2) {
return o1.compareTo(o2);
}
};
我排序,我从词典排序中得到这个排序( order3 ) :
and I sort, I get this ordering (order3) from lexicographic ordering:
{someRoot}
{someRoot}/aardvark.txt
{someRoot}/bar
{someRoot}/bar/file1.txt
{someRoot}/foo
{someRoot}/food.txt
{someRoot}/foo/abracadabra.txt
{someRoot}/foo/baz
{someRoot}/foo/baz/file3.txt
{someRoot}/foo/file2.txt
{someRoot}/zebra.txt
但我不想要这个订单(有问题:注意 food.txt
介于目录 foo
及其子项目之间),我想 order1 。我怎么能写一个比较器来帮我?
But I don't want this ordering (which has problems: note that food.txt
comes between directory foo
and its sub-items), I want order1. How can I write a Comparator to get me that?
推荐答案
这在我的测试中有效。
new Comparator<File>() {
@Override
public int compare(File first, File second) {
if (first.isDirectory() && second.isDirectory())
return first.compareTo(second);
if (first.isDirectory())
return this.compareToFile(first, second);
if (second.isDirectory())
return -(this.compareToFile(second, first));
return this.compareFiles(first, second);
}
private int compareFiles(File first, File second) {
File firstParentFile = first.getParentFile();
File secondParentFile = second.getParentFile();
if (isSubDir(firstParentFile, secondParentFile))
return -1;
if (isSubDir(secondParentFile, firstParentFile))
return 1;
return first.compareTo(second);
}
private int compareToFile(File directory, File file) {
File fileParent = file.getParentFile();
if (directory.equals(fileParent))
return -1;
if (isSubDir(directory, fileParent))
return -1;
return directory.compareTo(file);
}
private boolean isSubDir(File directory, File subDir) {
for (File parentDir = directory.getParentFile(); parentDir != null; parentDir = parentDir.getParentFile()) {
if (subDir.equals(parentDir)) {
return true;
}
}
return false;
}
这篇关于比较<文件>对于“目录优先”订购的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!