Sumit Shivhare
Sumit Shivhare

Reputation: 11

Comparison method violates its general contract! in java 11.0.4 2019-07-16 LTS version

I just getting below error and I also used this System.setProperty("java.util.Arrays.useLegacyMergeSort", "true") before sorting but still getting same error.

below are the comparator comparing value

Comparator<Balance> comp =  (t1, t2) -> {
BigDecimal a1 = t1.getBalance();
BigDecimal a2 = t2.getBalance();

 if (a1 == null && a2 == null) {
            return 0;
        } else if (a1 == null) {
            return -1;
        } else if (a2 == null) {
            return 1;
        }
        return a1.compareTo(a2);

};

and Balance is the class having one field of balance and I have also list of Balance and it's size is more than one thousand and below are the my stream.

List<Balance>result =  balances.stream()
                .sorted(comp)
                .collect(Collectors.toList());

still getting same error.

java.lang.IllegalArgumentException: Comparison method violates its general contract!
    at java.util.TimSort.mergeHi(TimSort.java:903) ~[?:?]
    at java.util.TimSort.mergeAt(TimSort.java:520) ~[?:?]
    at java.util.TimSort.mergeCollapse(TimSort.java:448) ~[?:?]
    at java.util.TimSort.sort(TimSort.java:245) ~[?:?]
    at java.util.Arrays.sort(Arrays.java:1515) ~[?:?]
    at java.util.stream.SortedOps$SizedRefSortingSink.end(SortedOps.java:353) ~[?:?]
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:485) ~[?:?]
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474) ~[?:?]
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913) ~[?:?]
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[?:?]
    at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578) ~[?:?]
    at com.giddh.api.services.v2.BalanceV2Service.applySortingToAccountBalanceReport(BalanceV2Service.java:106) ~[classes/:?]
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
    at jdk.internal.reflect.DelegatingMeth`enter code here`odAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
    at java.lang.reflect.Method.invoke(Method.java:566)

Upvotes: 0

Views: 586

Answers (1)

Nowhere Man
Nowhere Man

Reputation: 19565

The posted issue does not seem to be reproducible.

The comparator posted is equivalent of the following one:

Comparator<Balance> comp = Comparator.comparing(
    Balance::getBalance, Comparator.nullsFirst(Comparator.naturalOrder())
);

and it is quite stable.

Thus, either the actual comparison code differs from the presented snippet, or the elements in the array/collection of balances may get updated from another thread while sorting is being applied.

Upvotes: 0

Related Questions