содержит ошибочные результаты

У меня есть класс «CoAutoria», который должен содержать 2 экземпляра класса «Автор» (у которого пока есть только имя) и количество статей, которые есть у этих авторов. 10 соавторов (относительно количества статей) Я создал TreeSet «CoAutoria», чтобы хранить общее количество статей для каждой пары. Мне нужно просмотреть Карту лет, собрать разных авторов и их соответствующий Набор соавторов. Затем для каждой пары создайте экземпляр CoAutoria и: добавьте его в набор деревьев (если он еще не существует); или просто суммируйте его количество статей с существующим в наборе.

Я уже создал метод compareTo, чтобы вставить его в набор деревьев, и создал метод equals, чтобы порядок авторов не имел значения.

Вот основной код:`

public class CoAutoria implements Comparable<CoAutoria>
{    
private Autor autor1;
private Autor autor2;
private int artigosComum;
(...) 
}


@Override
public int compareTo(CoAutoria a2)
{
    String thisAutor1 = autor1.getNome();
    String thisAutor2 = autor2.getNome();
    String caAutor1 = a2.getAutor1().getNome();
    String caAutor2 = a2.getAutor2().getNome();
    if((autor1.equals(a2.getAutor1()) && autor2.equals(a2.getAutor2())) || (autor1.equals(a2.getAutor2()) && autor2.equals(a2.getAutor1())))
    {
        return 0;
    }
    else
    {               

       return 1;
    }        
}    
@Override
public boolean equals(Object o)
{
    if(this == o)
    {
        return true;
    }


    if( o == null || o.getClass() != this.getClass())
        return false;

    CoAutoria ca  = (CoAutoria) o;
    String thisAutor1 = autor1.getNome();
    String thisAutor2 = autor2.getNome();
    String caAutor1 = ca.getAutor1().getNome();
    String caAutor2 = ca.getAutor2().getNome();
    if((thisAutor1.equals(caAutor1) && thisAutor2.equals(caAutor2)) || (thisAutor1.equals(caAutor2) && thisAutor2.equals(caAutor1)))
    {
        return true;
    }
    else
    {               
        return false;
    }

}

Основная проблема заключается в следующем: когда я проверяю, есть ли в наборе уже определенный экземпляр «CoAutoria» (я использую метод contains() для TreeSet), он дает ошибочные результаты... иногда он правильно проверяет, что пара AB уже существует в этом наборе (в форме BA), но иногда его нет... Из того, что я читал, в contains используется метод equals, так что этого не должно происходить... верно?

[РЕДАКТИРОВАТЬ:] С момента первого сообщения я начал думать, что, возможно, проблема связана с сравнением.. Поэтому я изменил его на

public int compareTo(CoAutoria a2)
{
String thisAutor1 = autor1.getNome();
String thisAutor2 = autor2.getNome();
String caAutor1 = a2.getAutor1().getNome();
String caAutor2 = a2.getAutor2().getNome();
if(this.equals(a2))
{
    System.out.println("return 0");
    return 0;
}
else
{               
   int aux = thisAutor1.compareTo(caAutor1);
   if(aux != 0)
   {
       return aux;

   }
   else
   {
       return thisAutor2.compareTo(caAutor2);

   }

}        

}

Но это все еще дает мои плохие результаты.. Я думал, что понял это сейчас: если это та же «CoAutoria», я возвращаю 0, если нет, я просматриваю имена и упорядочиваю их по их значениям compareTo.. но чего-то не хватает


person A. Capelo    schedule 12.06.2013    source источник
comment
В вашем примере этого недостаточно, но.... Вместо использования contains выполните цикл, и вы, вероятно, обнаружите, что тестирование с equals() также не работает.   -  person Darius X.    schedule 12.06.2013
comment
@ Дариус X. Проблемы не с равными, а с функцией compareTo. Когда функция compareTo работает неправильно, метод contains для упорядоченных коллекций тоже не работает.   -  person greedybuddha    schedule 12.06.2013


Ответы (1)


Ваш метод contains не работает, потому что ваш метод compareTo всегда возвращает 0 или положительный результат, а не отрицательный. Это означает, что ваш compareTo несовместим. Правильная реализация должна возвращать 0, если авторы одни и те же, или положительные и отрицательные значения, если авторы разные.

Пример (при условии, что author1 отличается от author2):

 int i = author1.compareTo(author2); // i should be positive or negative
 int j = author2.compareTo(author1); // j should be the opposite of i

Ваш вернет 1 для обоих вышеперечисленных случаев, из-за чего упорядоченные коллекции не будут работать, поскольку ни один элемент никогда не будет smaller. В качестве другого примера представьте, что у вас есть двоичное дерево (упорядоченная коллекция), в котором есть элементы [1-10]. Если бы вы искали элемент 5, ваше бинарное дерево при сравнении 5 с любым элементом всегда говорило бы, что он равен или больше.

Как именно вы должны изменить его, зависит от вас. Но идея заключалась бы в том, чтобы отсортировать авторов по именам, затем перебрать обе коллекции и сравнить авторов вместе лексикографически.

РЕДАКТИРОВАТЬ: даже после редактирования ваших методов они все еще не согласованы. Попробуйте следующее, они не самые эффективные, но должны работать, если вы действительно не хотите оптимизировать скорость. Обратите внимание, что они сначала сортируются, чтобы убедиться, что автор1 и автор2 находятся в порядке, прежде чем они сравниваются с другим CoAutor, который также отсортирован. Я не проверяю значение null и предполагаю, что оба являются действительными авторами.

@Override
public boolean equals(Object o){
    if (o == null || !(o instanceof CoAutoria)) return false;
    if (o == this) return true;
    return this.compareTo((CoAutoria)o) == 0;
}

@Override
public int compareTo(CoAutoria o) {
    List<String> authors1 = Arrays.asList(autor1.getNome(), autor2.getNome());
    List<String> authors2 = Arrays.asList(o.autor1.getNome(), o.autor2.getNome());
    Collections.sort(authors1);
    Collections.sort(authors2);
    for (int i=0;i<authors1.size();i++){
        int compare = authors1.get(i).compareTo(authors2.get(i));
        if (compare != 0)
            return compare;
    }
    return 0;
}
person greedybuddha    schedule 12.06.2013
comment
Спасибо за ответ. Я попытался улучшить свой метод compareTo (я отредактировал начальный пост), но все равно делаю какую-то ошибку. - person A. Capelo; 13.06.2013
comment
Посмотрите мой исправленный ответ. Ваши методы все еще неверны, поэтому попробуйте то, что я предложил. - person greedybuddha; 13.06.2013
comment
Да, только что я понял, что если мои пары не будут упорядочены таким же образом, я не смогу использовать созданный мной метод, спасибо! Еще одно решение, которое, в моем случае, выполнимо, — это заказ авторов при создании экземпляра «CoAutoria». Но в ситуации, когда я не мог этого сделать, ваш метод был бы более полезным :) - person A. Capelo; 13.06.2013