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
Arrays
andCollections
may throw anIllegalArgumentException
Description: The sorting algorithm used by
java.util.Arrays.sort
and (indirectly) byjava.util.Collections.sort
has been replaced. The new sort implementation may throw anIllegalArgumentException
if it detects aComparable
that violates theComparable
contract. 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