Метод сравнения нарушает свой общий контракт, сортируя по разным свойствам - PullRequest
0 голосов
/ 04 декабря 2018

Необходимо отсортировать некоторые элементы на основе отметки времени / текущего часа и / или свойства name объекта person элемента в алфавитном порядке.Как бы я исправил IllegalArgumentException, который выдается в некоторых случаях?

    public static final Comparator<Item> sortByTimeAndName = new Comparator<Item>() {

            @Override
            public int compare(Item lhs, Item rhs) {
                if(lhs.getDate() != null && rhs.getDate != null){
                    if (lhs.getDate().getTime() < rhs.getDate().getTime()) {
                        return -1;
                    } else if (lhs.getDate().getTime() == rhs.getDate().getTime()) {
                        if (lhs.getHour() < rhs.getHour()) {
                            return -1;
                        } else if (lhs.getHour() == rhs.getHour()) {
                            if(lhs.getPerson().getName().compareTo(rhs.getPerson().getName()) == 0){
                              // if two persons have same name, sort by person id
                                if (lhs.getPerson().getID() < rhs.getPerson().getID()){
                                    return -1;
                                }
                            }
                            else{
                                return lhs.getPatient().getName().compareTo(rhs.getPatient().getName());
                            }
                        }
                    }
                }else{
                    if (lhs.getHour() < rhs.getHour()) {
                        return -1;
                    } else if (lhs.getHour() == rhs.getHour()) {
                        if(lhs.getPerson().getName().compareTo(rhs.getPerson().getName()) == 0){
                            if (lhs.getPerson().getID() < rhs.getPerson().getID()){
                                return -1;
                            }
                        }
                        else{
                            return lhs.getPerson().getName().compareTo(rhs.getPerson().getName());
                        }
                    }
                }

                return 1;
            }
        };

Трассировка стека:

Caused by java.lang.IllegalArgumentException: Comparison method violates its general contract!
       at java.util.TimSort.mergeLo(TimSort.java:761)
       at java.util.TimSort.mergeAt(TimSort.java:497)
       at java.util.TimSort.mergeCollapse(TimSort.java:421)
       at java.util.TimSort.sort(TimSort.java:210)
       at java.util.Arrays.sort(Arrays.java:1998)
       at java.util.Collections.sort(Collections.java:1900)
....

1 Ответ

0 голосов
/ 04 декабря 2018

Предположим, есть 3 объекта типа Item, таких как:для a: предположим, getDate() == nullдля b: предположим, getDate() != nullТаким образом, результат операторапредположим, что if (lhs.getHour() < rhs.getHour()) равно true, тогда a < bтакжедля b: предположим, getDate() != nullдля c: предположим, getDate() != nullТаким образом, результат операторапредположим, что if (lhs.getDate().getTime() < rhs.getDate().getTime()) равно true, тогда b < cтакжедля a: предположим, getDate() == nullдля c: предположим, getDate() != nullТаким образом, результат операторапредположим, что if (lhs.getHour() > rhs.getHour()) равно true, затем a > c(из-за финала return 1)

Как видите, есть противоречие:a < b и b < c, но a > cЯ считаю, что подобные случаи нарушают общий контракт метода сравнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...