假设我创建了一个对象并将其添加到数组列表中。如果我然后用完全相同的构造函数输入创建另一个对象,contains()方法是否会计算出两个对象是相同的?假设构造函数没有对输入做任何奇怪的事情,并且存储在两个对象中的变量是相同的。
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;
}
}
这是类应该如何实现有contains()返回true吗?
其他帖子已经解决了contains()如何工作的问题。
您的问题中同样重要的一个方面是如何正确地实现equals()。这个问题的答案取决于这个特定类的对象相等的构成。在你提供的例子中,如果你有两个x=5的不同对象,它们相等吗?这真的取决于你想要做什么。
如果你只对对象的相等性感兴趣,那么.equals()的默认实现(由object提供的)只使用标识符(即this == other)。如果这是你想要的,那么就不要在你的类上实现equals()(让它从Object继承)。你写的代码,虽然是正确的,如果你是为了标识,永远不会出现在一个真正的类b/c,它提供没有使用默认的Object.equals()实现的好处。
如果您刚刚开始学习这些东西,我强烈推荐Joshua Bloch的《Effective Java》一书。这是一本很棒的读物,涵盖了这类内容(以及当您试图做更多基于标识的比较时如何正确实现equals())
只是想指出,当value不是基本类型时,下面的实现是错误的:
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;
}
}
在这种情况下,我建议如下:
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;
}
}