sorting - java.lang.IllegalArgumentException: Comparison method violates its general contract! java.util.Date -
java.lang.illegalargumentexception: comparison method violates general contract! @ java.util.timsort.mergelo(timsort.java:747) @ java.util.timsort.mergeat(timsort.java:483) @ java.util.timsort.mergecollapse(timsort.java:410) @ java.util.timsort.sort(timsort.java:214) @ java.util.timsort.sort(timsort.java:173) @ java.util.arrays.sort(arrays.java:659) @ java.util.collections.sort(collections.java:217)
i sorting collection based on following comparator.
public static comparator<myclass> cmp_time_desc = new comparator<myclass>() { @override public int compare(myclass o1, myclass o2) { return o2.getordersendtime().compareto(o1.getordersendtime()); } };
the values non-null. , getordersendtime() object of java.util.date class.
i understand transitivity inconsistency, , assume class not have such issues. searched open issues, did not find on topic.
any ideas?
i had same exception, , happened when had java.util.date
, java.sql.timestamp
objects in same list/array when being sorted, running on java8. (this mix due objects being loaded database records timestamp
data type, , others being created manually, , objects having date
object in them.)
the exception doesn't happen every time sort same data set, , seems there have @ least 32 of these mixed objects in array occur.
if use legacy sort algorithm, doesn't occur (see how in ortomala lokni's answer).
this doesn't happen if use java.util.date
objects or java.sql.timestamp
objects in array.
so, issue seems timsort
combined compareto methods in java.util.date
, java.sql.timestamp
.
however, didn't pay me research why happening since fixed in java 9!
as workaround until java9 released , can our systems updated, have manually implemented comparator
uses gettime()
. seems work fine.
here code can used reproduce issue:
import java.sql.timestamp; import java.util.arraylist; import java.util.collections; import java.util.date; import java.util.list; import org.junit.test; public class timsortdateandtimestamptest { // same test data dates, timestamps, strings or longs not fail. // fails mixed timestamp , date objects @test public void testsortwithtimestampsanddatesfails() throws exception { list<date> dates = new arraylist<>(); dates.add(new timestamp(1498621254602l)); dates.add(new timestamp(1498621254603l)); dates.add(new timestamp(1498621254603l)); dates.add(new timestamp(1498621254604l)); dates.add(new timestamp(1498621254604l)); dates.add(new timestamp(1498621254605l)); dates.add(new timestamp(1498621254605l)); dates.add(new timestamp(1498621254605l)); dates.add(new timestamp(1498621254605l)); dates.add(new timestamp(1498621254606l)); dates.add(new timestamp(1498621254607l)); dates.add(new date(1498621254605l)); dates.add(new timestamp(1498621254607l)); dates.add(new timestamp(1498621254609l)); dates.add(new date(1498621254603l)); dates.add(new date(1498621254604l)); dates.add(new date(1498621254605l)); dates.add(new date(1498621254605l)); dates.add(new date(1498621254607l)); dates.add(new timestamp(1498621254607l)); dates.add(new date(1498621254608l)); dates.add(new timestamp(1498621254608l)); dates.add(new date(1498621254611l)); dates.add(new timestamp(1498621254612l)); dates.add(new timestamp(1498621254613l)); dates.add(new date(1498621254607l)); dates.add(new timestamp(1498621254607l)); dates.add(new timestamp(1498621254608l)); dates.add(new timestamp(1498621254609l)); dates.add(new timestamp(1498621254611l)); dates.add(new date(1498621254603l)); dates.add(new date(1498621254606l)); (int = 0; < 200; i++) { collections.shuffle(dates); collections.sort(dates); } } }
edit: have removed exception expectation can see throwing when run.
Comments
Post a Comment