Сравнить объекты в LinkedList.contains () - PullRequest
9 голосов
/ 15 февраля 2009

Я хочу, чтобы LinkedList.contains () возвращал true для пользовательского компаратора.

Предположим, у меня есть 1 LinkedList и 2 объекта

LinkedList<MyObject> myList = new LinkedList<MyObject>();

MyObject a = new MyObject("HELLO");
MyObject b = new MyObject("HELLO");

Технически, оба объекта идентичны с точки зрения сравнения (MyObject реализует Comparable)

(a == b) == true

однако, когда я делаю следующее, myList не возвращает true для myList.contains (b)

myList.add(a)
myList.contains(b) // == false

Я думаю, что его потому что содержит проверит ссылку на объект и увидит, что a и b - это 2 разных объекта. Есть ли способ сделать это, чтобы мне не пришлось расширять LinkedList для сравнения этих объектов?

Ответы [ 6 ]

26 голосов
/ 15 февраля 2009

LinkedList использует метод equals, а не Comparable.compareTo. Вы должны переопределить равно (и hashCode) в MyObject, чтобы решить проблему.

3 голосов
/ 15 февраля 2009

Вам необходимо переопределить методы .equals (Oject) и .hashCode () в классе MyObject (hashCode не требуется для List ... но когда вы перезаписываете equals, контракт говорит, что вы должны переопределить hashCode) .

В сущности, что содержит содержимое:

for(each item in the list)
{
    if(theCurrentItem.equals(theItemYouAreLookingFor))
    {
        return (true);
    }
}

return (false);

Посмотрите документацию для Object (для equals и hashCode) здесь

Также очень хорошая книга для чтения - Эффективная Java

3 голосов
/ 15 февраля 2009

Метод contains() использует equals(), чтобы определить, есть ли объект в списке. Я подозреваю, что ваш класс MyObject не переопределяет метод equals(), и именно поэтому myList.contains(b) возвращает false.

2 голосов
/ 15 февраля 2009

Документация для метода содержимого выглядит следующим образом:

Возвращает true, если эта коллекция содержит указанный элемент. Больше формально возвращает true тогда и только тогда, когда эта коллекция содержит хотя бы один элемент e такой, что (o == null? e == null : o.equals (e)).

Следовательно, вам необходимо переопределить метод equals (Object o) объекта MyObject.

Итак, для вашего примера:

public class MyObject {
  String myVal;

  public boolean equals(Object o ) {
    return ((MyObject)o).myVal.equals(myVal);
  }
}

Вам не нужно ничего реализовывать с помощью интерфейса Comparable.

2 голосов
/ 15 февраля 2009
( a == b ) == true

Вы имели в виду a.equals(b) и b.equals(a) return true? Это не то же самое , как проверка на равенство ссылок или проверка на a.compareTo(b) == 0.

LinkedList.contains() использует equals(), поэтому вы должны убедиться, что метод реализован правильно . equals() также должен соответствовать compareTo(), хотя это не является строго обязательным. Если вы используете структуру данных на основе хеша (например, HashSet), вы должны убедиться, что hashCode() реализован правильно .

1 голос
/ 15 февраля 2009

Вместо того, чтобы использовать LinkedList для поиска по каждому элементу, вы рассматривали возможность использования нового HashSet (Comparator). Это позволит эффективно сравнить элементы, чтобы найти совпадение.

...