2013-04-18 5 views
2

Ниже приведен фрагмент кода, который приводит к исключению, как указано,Метод сравнения нарушает его общий контракт Exception

Код:

Collections.sort(arrayList, new Comparator() 
{ 
    public int compare(Object o1, Object o2) 
    { 
     TypeAdapterSort tas1 = (TypeAdapterSort) o1; 
     TypeAdapterSort tas2 = (TypeAdapterSort) o2; 
     if (tas1.order < tas2.order) 
      return -1; 
     else 
      return 1; 
    } 
}); 

Исключение:

java.lang.IllegalArgumentException: Comparison method violates its general contract! 
       at java.util.TimSort.mergeLo(TimSort.java:747) 
       at java.util.TimSort.mergeAt(TimSort.java:483) 
       at java.util.TimSort.mergeForceCollapse(TimSort.java:426) 
       at java.util.TimSort.sort(TimSort.java:223) 
       at java.util.TimSort.sort(TimSort.java:173) 
       at java.util.Arrays.sort(Arrays.java:659) 
       at java.util.Collections.sort(Collections.java:217) 

Когда я запускаю тот же кода как автономной программы, проблема никогда не возникает. В чем проблема с компаратором? Есть ли способ воспроизвести проблему в автономном коде?

Эта проблема возникает только на Java 1.7, так как произошли изменения в реализации на Arrays.sort & Collections.sort. Как изменить приведенный выше код, чтобы избежать проблемы ?. Также, как воспроизвести эту проблему в автономном коде?

+1

если заказ типа 'Integer' можно вернуть' tas1.order.compareTo (tas2.order) ' –

+0

, что вы имеете в виду под«отдельной программой»? Вернее, какой другой вариант запуска кода, на который вы ссылаетесь? –

+0

Возможный дубликат [«Метод сравнения нарушает его общий контракт!»] (Http://stackoverflow.com/questions/8327514/comparison-method-violates-its-general-contract) –

ответ

3

Вам необходимо вернуть 0 на равных объектах.

 if (tas1.order < tas2.order){ 
      return -1; 
     } else if (tas1.order == tas2.order){ 
      return 0; 
     } else { 
      return 1; 
     } 

Вы можете прочитать here более

+0

Но почему проблема не воспроизводится при запуске как автономная программа, где значение переменной последовательности intance поддерживается одинаково? – Mohan

+0

Сравнение должно быть транзитивным. Ваш код отсутствует. Поэтому вместо неправильной работы он заявляет вам, что ваш код неисправен. Я думаю, что это очень хорошее поведение. – BobTheBuilder

+0

@baraky Возможно, вы можете написать 'tas1.order == tas2.order', вы наверняка пропустили двойное« = »вместо ... присваивания;) – Mik378

Смежные вопросы