Reputation: 3
I need to sort an array of files by the date which is part of the name of the file e.g.: "20200611_2130.dat"
.
I tried doing it with:
Arrays.sort(files,new FileNameComparator());
public class FileNameComparator implements Comparator<File> {
private static SimpleDateFormat formatter =
new SimpleDateFormat("YYYYddMM_HHmm");
@Override
public int compare(File a, File b) {
try {
return asTime(a.getName()) > asTime(b.getName()) ? 1 : -1;
} catch (ParseException e) {
e.printStackTrace();
}
return 0;
}
private static long asTime(String filename) throws ParseException {
return formatter.parse(
filename.substring(0, filename.lastIndexOf("."))).getTime();
}
}
I know there is a lot to fix here, but right now I would like to understand why I get:
"Comparison method violates its general contract!"
Upvotes: 0
Views: 122
Reputation:
Code review:
"yyyyddMM_HHmm"
if 20200611_2130.dat
is Fri Nov 06 21:30:00
.catch
block, for example Long.MIN_VALUE
.Your code might look something like this:
private static SimpleDateFormat formatter =
new SimpleDateFormat("yyyyddMM_HHmm");
private static long asTime(String filename) {
try {
Date date = formatter.parse(
filename.substring(0, filename.lastIndexOf(".")));
return date.getTime();
} catch (ParseException e) {
return Long.MIN_VALUE;
}
}
public static void main(String[] args) {
String[] fileNames = {
"20200611_2130.dat",
"20201511_2130.dat",
"20200605_2130.dat",
"20100611_2130.dat",
"picture.jpg"};
Arrays.sort(fileNames, Comparator
.<String>comparingLong(name -> asTime(name))
.thenComparing(Comparator.naturalOrder()));
Arrays.stream(fileNames).forEach(System.out::println);
}
Output:
picture.jpg
20100611_2130.dat
20200605_2130.dat
20200611_2130.dat
20201511_2130.dat
Upvotes: 0
Reputation: 317
@Bertolla you need to add a equals case. if equal return 0 else -1. then do a greater or smaller comparison case.
Upvotes: 0
Reputation: 183
Your comparator not works when a==b. It has to return 0. Your current implementation returns -1. You should consider the case where a==b and return 0 if true, then handle the case where filenames are different.
Upvotes: 1