2016-12-26 3 views
1

Я смотрю какой-то унаследованный код, и я нашел раздел, который вызывает у меня ошибку «Сравнительный метод нарушает общий контракт!». Я понимаю, что эта ошибка является результатом того, что код не является транзитивным, но я не совсем понимаю, как правильно его исправить.Java: IllegalArgumentException

Вот код, который отвечает за ошибки.

private void sortHistories(List<History> histories) { 
     Collections.sort(histories, new Comparator<History>() { 

      @Override 
      public int compare(History o1, History o2) { 

       return o1 == o2 ? 0 
         : o1 == null ? -1 
         : o2 == null ? 1 
         : o1.getFamilyMembers().equals(o2.getFamilyMembers()) ? 0 //getFamilyMembers() returns a string 
         : o1.getFamilyMembers() == null ? -1 
         : o2.getFamilyMembers() == null ? 1 
         : o2.getFamilyMembers().compareTo(o2.getFamilyMembers()) != 0 ? 
           o2.getFamilyMembers().compareTo(o2.getFamilyMembers()) 
         : o1.getDisease().equals(o2.getDisease()) ? 0 //getDisease() also returns a string 
         : o1.getDisease() == null ? -1 
         : o2.getDisease() == null ? 1 
         : o1.getDisease().compareTo(o2.getDisease()); 
      } 
     }); 
    } 

Первоначально код использует ==, а не equals() при сравнении строк getDisease() и getFamilyMembers(). Я думал, что внесение изменений с == в equals() устранит проблему, но это не тот случай.

+3

вы должны проверить o1.getDise ase() равно null или нет до сравнения os.getDisease(), равно ли o2.getDisease() – haifzhan

+1

. '==' была оптимизацией. Две строки ниже, 'o2.getFamilyMembers(). CompareTo (o2.getFamilyMembers())! = 0' делает реальную работу. Поэтому '== 1 * был * правильным (и избыточным). –

+0

@HaifengZhang Я пробовал это, в дополнение к перемещению еще одной нулевой проверки, но я все еще получаю ошибку. Я опубликовал свой обновленный код выше. –

ответ

0

Внимательно прочитайте документацию. Завершение этого исключения - это новая функция Java7.

Подробнее здесь :: https://stackoverflow.com/a/8327575/3080158

Старое поведение может быть сконфигурирован с новым свойством системы: java.util.Arrays.useLegacyMergeSort.

http://www.oracle.com/technetwork/java/javase/compatibility-417013.html#source

enter image description here

http://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html

enter image description here

+0

Согласитесь, что это может избавиться от исключения, но оно не будет исправлять порядок сортировки, не так ли? –

+0

Да, для фиксации компаратора порядка сортировки следует следовать контракту, т. Е. Для lt -1, gt 1 и равен 0, с транзитивностью. – RBanerjee

+0

Это понятно, так, как OP делает это с учетом кода, который был опубликован? –

2

Раствор, благодаря HaifengZhang и YoungHobbit, является:

public int compare(History o1, History o2) { 
       return o1 == o2 ? 0 
         : o1 == null ? -1 
         : o2 == null ? 1 
         : o1.getFamilyMembers() == null ? -1 
         : o2.getFamilyMembers() == null ? 1 
         : o1.getFamilyMembers() == o2.getFamilyMembers() ? 0 
         : o2.getFamilyMembers().compareTo(o1.getFamilyMembers()) != 0 ? 
           o2.getFamilyMembers().compareTo(o1.getFamilyMembers()) 
         : o1.getDisease() == null ? -1 
         : o2.getDisease() == null ? 1 
         : o1.getDisease() == o2.getDisease() ? 0 
         : o1.getDisease().compareTo(o2.getDisease()); 
      } 
Смежные вопросы