10

我希望能够让 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) == 真

但是,当我执行以下操作时,myList 不会为 myList.contains(b) 返回 true

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

我认为它是因为 contains 将检查对象引用并看到 a 和 b 是 2 个不同的对象。有什么办法可以做到,所以我不必扩展 LinkedList 来比较这些对象?

4

6 回答 6

27

LinkedList 使用 equals 方法,而不是 Comparable.compareTo。您应该覆盖 MyObject 中的 equals(和 hashCode)来解决问题。

于 2009-02-14T21:16:06.273 回答
3

contains()方法用于equals()确定对象是否在列表中。我怀疑您的类MyObject没有覆盖该equals()方法,这myList.contains(b)就是返回的原因false

于 2009-02-14T21:16:57.567 回答
3

您需要覆盖 MyObject 类中的 .equals(Oject) 和 .hashCode() 方法(List 不需要 hashCode ......但是当您覆盖 equals 时,合同说您必须覆盖 hashCode)。

本质上, contains 的作用是:

for(列表中的每一项)
{
    if(theCurrentItem.equals(theItemYouAreLookingFor))
    {
        返回(真);
    }
}

返回(假);

在这里查看 Object (for equals and hashCode) 的文档

《 Effective Java》也是一本非常值得阅读的书

于 2009-02-14T21:18:22.900 回答
2
( a == b ) == true

你的意思是a.equals(b)然后b.equals(a)返回true?这与检查引用相等性不同,也不同于a.compareTo(b) == 0检查.

LinkedList.contains()使用equals(),因此您必须确保该方法已正确实施equals()也应该与 一致compareTo(),尽管这不是绝对必要的。如果您使用的是基于散列的数据结构(例如HashSet),则必须确保hashCode()正确实施

于 2009-02-14T21:16:24.840 回答
2

contains 方法的文档如下:

如果此集合包含指定元素,则返回 true。更正式地说,当且仅当此集合包含至少一个元素 e 满足 (o==null ? e==null : o.equals(e)) 时才返回 true。

因此,您需要重写 MyObject 的 equals(Object o) 方法。

所以对于你的例子:

public class MyObject {
  String myVal;

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

您不需要使用 Comparable 接口实现任何东西。

于 2009-02-14T21:17:01.407 回答
1

您是否考虑过使用新的 HashSet(Comparator),而不是使用 LinkedList 搜索每个元素。这将有效地比较元素以找到匹配项。

于 2009-02-15T07:26:30.817 回答