【问题标题】:Compare objects in LinkedList.contains()比较 LinkedList.contains() 中的对象
【发布时间】:2010-10-07 16:20:29
【问题描述】:

我希望能够让 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 来比较这些对象?

【问题讨论】:

    标签: java linked-list contains equality


    【解决方案1】:

    LinkedList 使用 equals 方法,而不是 Comparable.compareTo。你应该在 MyObject 中 override equals (and hashCode) 来解决这个问题。

    【讨论】:

    • 如果我做不到怎么办?有没有获取自定义比较器的 Set?
    • 知道为什么@Override 标签说我在 MyObject 中定义 equals 方法时没有覆盖任何东西吗?
    • 弄清楚了:方法定义 public boolean equals(MyObject obj) 不会触发覆盖,但 public boolean equals(Object obj) 会。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      contains 的作用基本上是这样的:

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

      查看 Object (for equals and hashCode) here的文档

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

      【讨论】:

        【解决方案4】:
        ( a == b ) == true
        

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

        LinkedList.contains() 使用equals(),所以你必须确保方法是implemented correctlyequals() 也应该与compareTo() 一致,尽管这不是绝对必要的。如果您使用基于哈希的数据结构(例如HashSet),则必须确保hashCode()implemented correctly

        【讨论】:

          【解决方案5】:

          contains 方法的文档如下:

          如果此集合返回 true 包含指定的元素。更多的 正式地,当且仅当返回 true 此集合至少包含一个 元素 e 使得 (o==null ? e==null : o.equals(e))。

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

          所以对于你的例子:

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

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

          【讨论】:

            【解决方案6】:

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

            【讨论】:

            • HashSet 未重载以在其构造函数中获取 Comparator 对象。你是说 TreeSet 吗?
            猜你喜欢
            • 1970-01-01
            • 2013-11-01
            • 2013-12-22
            • 2014-07-28
            • 2018-11-03
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多