这不是传递性的。
元素的线性排序是不可能的。
通过反例证明。
假设你已经在小写拿到3个DownloadFile
S(c
,b
,a
)与名称:
c.par2
b.notpar2
a.par2
为了简化,我将使用<
的线性排序和小写名称。
c.par2 < b.notpar2
和b.notpar2 < a.par2
,但它不是真的c.par2 < a.par2
。
这种关系不是transitive。
在逻辑...它会像:
cRb
和bRa
,但它是不正确的cRa
。
所有你需要做的是回答如何线性订购您的文件...
我会去这样的事情:
if(aMethodOnThis < aMethodOnOther) {
return -1; //or 1
}
if(aCompletelyDifferentCriterium) {
//...
}
return 0; //or return thisFileName.compareTo(otherFileName);
的return 0
末是非常重要的,因为它返回为不可区分的文件。
在这种情况下:
public class DownloadFile implements Comparable<DownloadFile>{
String filename;
DownloadFile(String filename) {
this.filename = filename;
}
public String getFilename() {
return this.filename;
}
@Override
public String toString() {
return this.getFilename();
}
@Override
public int compareTo(DownloadFile downloadFile) {
String thisStr = this.filename.toLowerCase();
String oStr = downloadFile.getFilename().toLowerCase();
if(thisStr.endsWith(".rar")) {
if(!oStr.endsWith(".rar"))
return -1;
}
if(oStr.endsWith(".rar")) {
if(!thisStr.endsWith(".rar"))
return 1;
}
if(thisStr.matches(".*\\.r[0-9]{2,}$")) {
if(!oStr.matches(".*\\.r[0-9]{2,}$"))
return -1;
}
if(oStr.matches(".*\\.r[0-9]{2,}$")) {
if(!thisStr.matches(".*\\.r[0-9]{2,}$"))
return 1;
}
if(thisStr.endsWith(".par2")) {
if(!oStr.endsWith(".par2"))
return -1;
}
if(oStr.endsWith(".par2")) {
if(!thisStr.endsWith(".par2"))
return 1;
}
return thisStr.compareTo(oStr);
}
public static void main(String[] args) {
List<DownloadFile> fileList = new ArrayList<>();
fileList.add(new DownloadFile("a.rar"));
fileList.add(new DownloadFile("b.rar"));
fileList.add(new DownloadFile("a.r01"));
fileList.add(new DownloadFile("b.r01"));
fileList.add(new DownloadFile("a.r10"));
fileList.add(new DownloadFile("b.r10"));
fileList.add(new DownloadFile("a.par2"));
fileList.add(new DownloadFile("b.par2"));
fileList.add(new DownloadFile("a.other"));
fileList.add(new DownloadFile("b.other"));
Collections.shuffle(fileList);
Collections.sort(fileList);
System.out.println(fileList);
}
}
把它缩短Predicate<String>
从Java 8就派上用场了;)
@Override
public int compareTo(DownloadFile downloadFile) {
String thisStr = this.filename.toLowerCase();
String oStr = downloadFile.getFilename().toLowerCase();
List<Predicate<String>> conditionList = new ArrayList<>();
conditionList.add(s -> s.endsWith(".rar"));
conditionList.add(s -> s.matches(".*\\.r[0-9]{2,}$"));
conditionList.add(s -> s.endsWith(".par2"));
for(Predicate<String> condition : conditionList) {
int orderForCondition =
conditionHelper(thisStr, oStr, condition);
if(orderForCondition != 0)
return orderForCondition;
}
return thisStr.compareTo(oStr);
}
private int conditionHelper(String firstStr, String secondStr,
Predicate<String> condition) {
if(condition.test(firstStr))
if(!condition.test(secondStr))
return -1;
if(condition.test(secondStr))
if(!condition.test(firstStr))
return 1;
return 0;
}
首先,你知道这个错误的最可能的原因之一? http://stackoverflow.com/a/8327575/1743880 – Tunaki
所有带有“.r02”结尾的文件都必须在最后带有“.par”的文件之前出现? –
@GrzegorzGórkiewicz你的意思是在最后那些带有“.par2”的人之前?对,那是正确的。 – Matthias