我的应用程序比较了文件名,一个用户得到了“比较方法违反了它的通用java合同”。但我不能重现错误。
我的问题是:当我的@Override compare()方法返回0时,是否可以,这意味着对象是相等的?
这是我的代码:
两种类型的排序: 1)按上次修改日期排序2)按文件名中的正则表达式数字排序。
public class FileComparator implements Comparator<File> {
int sortType;
public FileComparator(int sortType) {
this.sortType = sortType;
}
@Override
public int compare(File f1, File f2) {
int result;
try {
switch (sortType) {
case Constants.SORT_BY_DATE:
result = f1.lastModified() > f2.lastModified() ? 1 : -1;
break;
case Constants.SORT_BY_DIGID:
result = checkByDigit(f1, f2);
break;
default:
result = f1.lastModified() > f2.lastModified() ? 1 : -1;
break;
}
return result;
} catch (Exception e) {
return 0;
}
}
private static int checkByDigit(File f1, File f2) {
String regEx;
Pattern p;
Matcher m1;
Matcher m2;
try {
String f1Name = f1.getName().toUpperCase();
String f2Name = f2.getName().toUpperCase();
// "ScanImage _ 001"
regEx = "(SCANIMAGE)(\\D*)(\\d+)";
p = Pattern.compile(regEx);
m1 = p.matcher(f1Name);
m2 = p.matcher(f2Name);
if (m1.find() && m2.find()) {
return Integer.parseInt(m1.group(3)) > Integer.parseInt(m2.group(3)) ? 1 : -1;
}
// "No_digits_here_001",""No_digits_here_002"
regEx = "(\\D+)(\\d+)";
p = Pattern.compile(regEx);
m1 = p.matcher(f1Name);
m2 = p.matcher(f2Name);
if (m1.find() && m2.find()) {
return Integer.parseInt(m1.group(2)) > Integer.parseInt(m2.group(2)) ? 1 : -1;
}
// We didnt find any digit, use lexicographically compare
return f1.compareTo(f2);
} catch (Exception e) {
//
}
return 0;
}
}发布于 2016-04-20 14:43:38
在这种特定情况下,您在比较aaa_002、ccc_001和bbb等名称时会遇到问题。您的代码并不能真正决定正确的顺序。一种选择是将所有包含数字序列的文件排在不包含数字序列的文件之后。
boolean m1find = m1.find();
boolean m2find = m2.find();
if(m1find || m2find) {
if (m1find && m2find) {
return Integer.compare(Integer.parseInt(m1.group(3)) > Integer.parseInt(m2.group(3)));
} else {
return Boolean.compare(m1find, m2find);
}
}这个问题也可能来自排序过程中lastModified时间的改变,但它不太可能经常发生。
发布于 2016-04-20 14:50:48
当您对上次修改的时间进行排序时,参数的顺序很重要,特别是在上次修改的时间相同的情况下。使用Long#compare。
https://stackoverflow.com/questions/36733974
复制相似问题