如果省略第3-5行,则此equals()方法将产生相同的输出(我将这些行编号)。这些界限有什么意义?
/** Return true if that Beetle has the same parts as this one. */
public boolean equals(Object that) {
3. if (this == that) {
4. return true;
5. }
if (that == null) {
return false;
}
if (getClass() != that.getClass()) {
return false;
}
Beetle thatBeetle = (Beetle) that;
return body == thatBeetle.body
&& eyes == thatBeetle.eyes
&& feelers == thatBeetle.feelers
&& head == thatBeetle.head
&& legs == thatBeetle.legs
&& tail == thatBeetle.tail;
}
答案 0 :(得分:3)
检查==引用相等是快速的,如果是,则将对象与自身进行比较 - 因此定义相等。
这通常用于比较对象的第一步,因为它比比较所有细节要快得多。但它更常用于调用者/客户端函数,而不是在equals()实现中。
例如,在线性搜索中:
public int indexOfBeetle (Beetle beetle, List<Beetle> list) {
for (int i = 0; i < list.size(); i++) {
Beetle cand = list.get( i);
if (cand == beetle || cand.equals( beetle))
return i; // Found.
}
// Not Found.
return -1;
}
答案 1 :(得分:2)
运算符==
检查对象是否与内存中的实例相同,而当您覆盖equals
时,通常需要执行逻辑测试。
我们举一个例子:
public class Person {
private String name;
// Here there are constructor and getters and setters
}
现在让我们运行以下几行:
Person a = new Person();
Person b = a;
Person c = new Person();
如果您将这些实例与==
进行比较,那么您将获得以下内容:
a == a ==> true
a == b ==> true
a == c ==> false
现在,让我们设置名称:
a.setName("Joe"); // This also sets b because they're the same object
c.setName("Joe");
如果我们equals
看起来像这样:
public boolean equals (Object other) {
if(other == this) return true;
if(other instanceof Person == false) return false;
if(this.getName().equals(((Person) other).getName())) return true;
}
即使a.equals(c)
为假,我们现在也会true
为a==c
。
那么,为什么我们有第一行? - 某些对象的相等性计算成本更高,并且通过在开头检查这个条件你可能会节省一些不必要的计算
答案 2 :(得分:1)
这样做是检查两个对象是否指向相同的内存地址。使用没有它的.equals你将获得相同的结果,因为如果它们指向相同的内存地址,那么显然它们是等于的。但这样做的速度要快得多,这就是为什么大多数开发人员将这些内容放在.equals上的原因