比较 LinkedList.contains() 中的对象

Posted

技术标签:

【中文标题】比较 LinkedList.contains() 中的对象【英文标题】:Compare objects in 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 来比较这些对象?

【问题讨论】:

【参考方案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 correctly。 equals() 也应该与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 吗?

以上是关于比较 LinkedList.contains() 中的对象的主要内容,如果未能解决你的问题,请参考以下文章

java对象的比较

JavaScript 比较操作符,严格比较===

CDateTimeCtrl类型的日期如何比较大小

java中Comparable和Comparator两种比较器的区别

BigDecimal 怎么比较大小

js两个时间大小的比较问题(只有时间比较,比如14:00和15:00的比较)