I have a list of filenames and want to compare these in the following order:
- all names ending with ".rar" should come before files with ".r01", ".r02", ...
- all names ending with ".par2" should come after files with with any other suffix
So I am using the following compareTo
method for one of my Java classes:
public class DownloadFile implements Comparable<DownloadFile>
{
// custom code ...
@Override
public int compareTo(DownloadFile other)
{
if(other == null)
throw new NullPointerException("Object other must not be null");
// special cases -- .rar vs .par2 etc.
String thisStr = filename.toLowerCase();
String oStr = other.getFilename().toLowerCase();
if(thisStr.endsWith(".rar") && oStr.matches(".*\\.r[0-9]{2,}$"))
return -1;
if(thisStr.matches(".*\\.r[0-9]{2,}$") && oStr.endsWith(".rar"))
return 1;
if(!thisStr.endsWith(".par2") && oStr.endsWith(".par2"))
return -1;
if(thisStr.endsWith(".par2") && !oStr.endsWith(".par2"))
return 1;
// normal comparison based on filename strings
return thisStr.compareTo(oStr);
}
}
However, on some data this leads to the following execption:
Exception in thread "Thread-12" java.lang.IllegalArgumentException: Comparison method violates its general contract!
I tried to understand what I am missing here, but I can't find the issue.
Can you spot where I am violating the contract?
PS: If I comment out the second two if
s, then the exeception is still thrown. So the problem lies with the first two if
s.