0

The problem started a year after writing the code. I always use Java 8 and the version has not changed. What is wrong in my code? I read the answers at "Comparison method violates its general contract!"

but these answers do not help

For me use System.setProperty ("java.util.Arrays.useLegacyMergeSort", "true"); not a decision.

private static Comparator<R> compareByFirstNumbersOfName() {
            Comparator<R> byFirstNumbersOfName = (r1, r2) ->
            {
                String[] arg0 = getFirstNumbersFromName(r1.getName());
                String[] arg1 = getFirstNumbersFromName(r2.getName());

                if (arg0 == null) {
                    return 1;
                }

                if (arg1 == null) {
                    return -1;
                }

                int length = arg0.length;
                if (arg1.length > arg0.length) {
                    length = arg1.length;
                }

                for (int i = 0; i < length; i++) {
                    String s0 = null;
                    if (i < arg0.length) {
                        s0 = arg0[i];
                    }
                    Integer i0 = (s0 == null) ? 0 : Integer.parseInt(s0);
                    String s1 = null;
                    if (i < arg1.length) {
                        s1 = arg1[i];
                    }
                    Integer i1 = (s1 == null) ? 0 : Integer.parseInt(s1);
                    if (i0.compareTo(i1) < 0) {
                        return -1;
                    } else if (i1.compareTo(i0) < 0) {
                        return 1;
                    }
                }
                return 0;
            };

            return byFirstNumbersOfName;
        }

        private static String[] getFirstNumbersFromName(String name) {
            if (firstSymbolIsNotDigit(name)) {
                return null;
            }
            String mayBeDigits = cutTextBeforeSpace(name);
            if (textHasOnlyDigitsAndDots(mayBeDigits)) {
                return mayBeDigits.split("\\.");
            }
            return null;
        }

        private static boolean textHasOnlyDigitsAndDots(String mayBeDigits) {
            return !Stream.of(mayBeDigits.split("\\."))
                    .anyMatch(md -> !NumberUtils.isDigits(md));
        }

        private static String cutTextBeforeSpace(String name) {
            return name.substring(0, name.indexOf(" "));
        }

error displayed: "Cause: java.lang.RuntimeException: java.lang.IllegalArgumentException: Comparison method violates its general contract!"

  • 2
    I guess you should add `if (arg0 == null && arg1==null) { return 0;}`. – minus Aug 23 '19 at 09:44
  • it will solve the problem but will provoke NullPointerException here: int length = arg0.length; – Sorokin Roman Aug 23 '19 at 11:57
  • 1
    Not if you put it before the first null check. Like: `if (arg0 == null && arg1==null) { return 0;} else if (arg0 == null ) { return 1;} else if (arg1==null) { return -1;}` – minus Aug 23 '19 at 12:17

0 Answers0