一个ArrayList的contains()方法如何评估对象?

说我创build一个对象,并将其添加到我的ArrayList 。 如果我然后创build具有完全相同的构造函数input的另一个对象,将contains()方法评估这两个对象是相同的? 假设构造函数不会对input做任何有趣的事情,并且存储在两个对象中的variables是相同的。

 ArrayList<Thing> basket = new ArrayList<Thing>(); Thing thing = new Thing(100); basket.add(thing); Thing another = new Thing(100); basket.contains(another); // true or false? 

 class Thing { public int value; public Thing (int x) { value = x; } equals (Thing x) { if (x.value == value) return true; return false; } } 

这是如何实现classcontains()返回true

ArrayList implements列表接口。

如果您查看contains方法的List的Javadoc,您会看到它使用equals()方法来评估两个对象是否相同。

我认为正确的实施应该是

 public class Thing { public int value; public Thing (int x) { this.value = x; } @Override public boolean equals(Object object) { boolean sameSame = false; if (object != null && object instanceof Thing) { sameSame = this.value == ((Thing) object).value; } return sameSame; } } 

ArrayList使用在类中实现的equals方法(您的情况Thing类)来执行equals比较。

通常,每次重写equals() ,也应该重写hashCode() equals() ,即使只是为了提高性能。 HashCode()决定你的对象在进行比较时被分类到哪个“bucket”,所以hashCode equal()求值为true的任何两个对象都应该返回相同的hashCode value() 。 我不记得hashCode()的默认行为(如果它返回0,那么你的代码应该工作,但慢,但如果它返回的地址,那么你的代码将失败)。 我记得很多次,当我的代码失败,因为我忘了重写hashCode() 。 🙂

它在对象上使用equals方法。 因此,除非Thing重写equals并使用存储在对象中的variables进行比较,否则contains()方法不会返回true。

 class Thing { public int value; public Thing (int x) { value = x; } equals (Thing x) { if (x.value == value) return true; return false; } } 

你必须写:

 class Thing { public int value; public Thing (int x) { value = x; } public boolean equals (Object o) { Thing x = (Thing) o; if (x.value == value) return true; return false; } } 

现在它的工作;)

其他海报已经解决了关于contains()如何工作的问题。

你的问题的一个同样重要的方面是如何正确实现equals()。 而这个答案真的取决于什么构成这个特定类的对象平等。 在你提供的例子中,如果你有两个不同的对象,都有x = 5,它们是相等的吗? 这实际上取决于你想要做什么。

如果您只对对象相等感兴趣,那么.equals()(由Object提供的)的默认实现仅使用标识(即this == other)。 如果这就是你想要的,那么就不要在你的类上实现equals()(让它inheritanceObject)。 你编写的代码,如果你正在寻求身份authentication,那么这个代码将永远不会出现在一个真正的类B / C中,它不会使用默认的Object.equals()实现。

如果你刚刚开始使用这个东西,我强烈推荐Joshua Bloch的Effective Java书。 这是一个很好的阅读,并涵盖了这种事情(加上如何正确实现equals(),当你试图做比基于身份比较更多)

只是想要注意的是,当value不是基本types时,下面的实现是错误的:

 public class Thing { public Object value; public Thing (Object x) { this.value = x; } @Override public boolean equals(Object object) { boolean sameSame = false; if (object != null && object instanceof Thing) { sameSame = this.value == ((Thing) object).value; } return sameSame; } } 

在这种情况下,我build议如下:

 public class Thing { public Object value; public Thing (Object x) { value = x; } @Override public boolean equals(Object object) { if (object != null && object instanceof Thing) { Thing thing = (Thing) object; if (value == null) { return (thing.value == null); } else { return value.equals(thing.value); } } return false; } } 

来自JavaDoc的快捷方式:

boolean contains(Object o)

如果此列表包含指定的元素,则返回true。 更正式地,返回true当且仅当该列表包含至less一个元素e以使得(o == null?e == null:o.equals(e))

Interesting Posts