Why does this code
public class SponsoredComparator implements Comparator<SRE> {
public boolean equals(SRE arg0, SRE arg1){
return arg0.getSponsored()==arg1.getSponsored();
}
public int compare(SRE object1, SRE object2) {
Log.d("SponsoredComparator","object1.getName() == "+ object1.getName());
Log.d("SponsoredComparator","object1.getSponsored() == "+ object1.getSponsored());
Log.d("SponsoredComparator","object2.getName() == "+ object2.getName());
Log.d("SponsoredComparator","object2.getSponsored() == "+ object2.getSponsored());
Log.d("SponsoredComparator","compare return == "+ (object1.getSponsored() && object2.getSponsored() ? 0 : object1.getSponsored() ? -1 : 1));
return object1.getSponsored() && object2.getSponsored() ? 0 : object1.getSponsored() ? -1 : 1;
}
}
throw this exception: ERROR/AndroidRuntime(244): java.lang.IllegalArgumentException: Comparison method violates its general contract!
ERROR/AndroidRuntime(4446): at java.util.TimSort.mergeLo(TimSort.java:743)
The method sre.getSponsored() returns a boolean.
Thanks.
I suspect the problem occurs when neither value is sponsored. That will return 1 whichever way you call it, i.e.
x1.compare(x2) == 1
x2.compare(x1) == 1
That's invalid.
I suggest you change this:
object1.getSponsored() && object2.getSponsored()
to
object1.getSponsored() == object2.getSponsored()
in both places. I would probably actually extract this out a method with this signature somewhere:
public static int compare(boolean x, boolean y)
and then call it like this:
public int compare(SRE object1, SRE object2) {
return BooleanHelper.compare(object1.getSponsored(), object2.getSponsored());
}
That will make the code clearer, IMO.
I assume that you are using JDK 7. Check the following URL:
From http://www.oracle.com/technetwork/java/javase/compatibility-417013.html#source
Area: API: Utilities
Synopsis: Updated sort behavior for
ArraysandCollectionsmay throw anIllegalArgumentExceptionDescription: The sorting algorithm used by
java.util.Arrays.sortand (indirectly) byjava.util.Collections.sorthas been replaced. The new sort implementation may throw anIllegalArgumentExceptionif it detects aComparablethat violates theComparablecontract. The previous implementation silently ignored such a situation. If the previous behavior is desired, you can use the new system property,java.util.Arrays.useLegacyMergeSort, to restore previous mergesort behavior.Nature of Incompatibility: behavioral
RFE: 6804124
For more detailed info, see the bug database reference here.
The contract between equals() and compareTo() is that when equals() returns true, compareTo() should return 0 and when equals() is false compareTo should return -1 or +1.
BTW: I assume your compare() method is not called very often as the debug messages will use up a signficiant amount of CPU and memory.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With