2013-05-29 3 views
3

Хромосома содержит ряд результатов, сгенерированных по-разному. Метод compareTo фактически проверяет соответствие методов и соответственно возвращает результат.Как сделать метод compareTo общим договором?

возврата 1: комп = -5 ..- 1

возврата 0: комп = 0 (может произойти в различных сценариях, один из которых является то, что все баллы равны

возврата -1:. Комп = 1..5

public int compareTo(Chromosome o) { 
    if(o == null) 
     return(1); 
    int comp = 0; 
    comp += Double.compare(getScore(1),o.getScore(1)); 
    comp += Double.compare(getScore(2),o.getScore(2)); 
    comp += Double.compare(getScore(3),o.getScore(3)); 
    comp += Double.compare(getScore(5),o.getScore(5)); 
    comp += Double.compare(getScore(7),o.getScore(7)); 
    if(comp == 0) 
     return(0); 
    if(comp > 0) 
     return(1); 
    else 
     return(-1); 
} 

Мой вопрос, как сделать этот сценарий придерживаться правил, установленных договором для comparator Видимо это не так и я получаю:. java.lang.IllegalArgumentException : Сравнение по методу нарушает его общий контракт!

+0

Можно ли назвать старую версию Collection.sort, не требуя от пользователя, чтобы установить какое-то флаг в некоторых Java. ини? Кроме того, можно ли сообщить JVM игнорировать контракт? – jallmer

ответ

2

Если вы реализуете интерфейс Comparator, то вам нужно использовать этот метод (при условии, что ваш класс является общим с хромосомой Tpye):

int compare(Chromosome o1, Chromosome o2) 

Тем не менее, кажется, более соответствующий интерфейс для реализации в ваш случай сравнивается. http://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html

int compareTo(Chromosome o) 

Сопоставимые обычно реализуется, чтобы дать Экземпляры класса естественный порядок. Компаратор обычно представляет собой отдельный класс для того, что вы пытаетесь сравнить, и его можно использовать, чтобы дать вам несколько разных типов заказов.

Независимо от того, что вы реализуете, класс также должен быть набран:

class Chromosome implements Comparable<Chromosome> 

В противном случае аргументы должны быть Object, а не хромосома.

+0

Содержит ли компаратор один и тот же контракт? – jallmer

+0

Я так думаю, кроме того, что они разные методы с разными сигнатурами. В обоих случаях вы должны быть совместимы с equals(), хотя это не строгое требование в соответствии с JavaDoc. Также рекомендуется, чтобы Comparator реализовал Serializable. Кроме того, оба должны вызывать исключение NullPointerException для null. – zetches

0

Ват, который вы пытаетесь реализовать, кажется, что одна хромосома больше другой, если у нее больше очков, которые больше, чем соответствующие друг другу. К сожалению, это не дает четкого приоритета. То есть вы не можете гарантировать, что все значения o1 = o2 и o2 = o3 o1 = o3 истинны. Это может привести к бесконечному циклу в упорядочении или, используя более продвинутый алгоритм, который вы сталкиваетесь. Поэтому вам нужно найти другой алгоритм, обеспечивающий стабильную сортировку.

Подходы:

  1. Сравните сумму баллов
  2. Определение приоритета оценка (score2 только по сравнению, если score1 равно и так далее)
+0

Спасибо, 1) кажется, что я делаю, не так ли? Я добавляю результаты отдельных сравнений, которые должны быть прямолинейными, но, похоже, не работают должным образом. – jallmer

1

Выработать немного на Sir Ответ RotN:

Метод compareTo должен придерживаться двух свойств:

  • сравнение является симметричным, т.е., если A=B затем B=A и если A<B затем B>A
  • сравнение транзитивно, т.е., Если A<B и B<C затем A<C, и если A=B и B=C затем A=C

Первое свойство выполнено для сравнения, но второй нет. Рассмотрим следующий пример из теории голосования: у нас есть 3 человека, которые голосуют за 3 альтернативы. Побеждает наивысшая ранжированная альтернатива. Известно, что это может привести к двусмысленной ситуации, когда ни одна альтернатива не побеждает.


В вашем случае это люди, а хромосомы - альтернативы. Вместо 5 баллов я использую только 3, так как этого достаточно, чтобы показать проблему. У меня есть 3 хромосомы, A, B и C, с баллами следующим образом:

A: 1, 2, 3 
B: 2, 3, 1 
C: 3, 1, 2 

Это не трудно понять, что A<B, B<C, иC<A, поэтому ваше сравнение не является транзитивным.


Вы могли бы решить эту проблему, заказав хромосомы лексический:

public int compareTo(Chromosome o) { 
    if(o == null) 
     return(1); 
    int[] indices = {1, 2, 3, 5, 7}; 
    for (int i : indices) { 
     int c = Double.compare(getScore(i),o.getScore(i)); 
     if (c != 0) 
      return c; 
    } 
    return 0; 
} 
+0

Отлично, это гвоздь проблема. Как я могу обойти это? – jallmer

+0

@jallmer Это действительно зависит от ваших требований. Является ли порядок важным или вам нужен какой-то произвольный заказ? –

+0

Идеальный заказ не имеет принципиального значения, но его следует заказать. – jallmer

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