可能重复:
Why .equals method is failing on two same value objects?
这很简单,但我显然错过了一些非常大的东西。
Cat cat1 = new Cat("bob");
Cat cat2 = new Cat("bob");
System.out.println(cat1 == cat2);
//false since these references point to diferent objects
System.out.println(cat1.equals(cat2));
//returns false also??
Cat
只是一个只有名字的简单类。
这里发生了什么,equals()
如何运作?我的印象是它比较了对象的所有字段。似乎情况并非如此。
我是否需要为所有课程覆盖它?
答案 0 :(得分:7)
是
java.lang.Object
提供了equals()
和hashCode()
的基本实现。特别是,他们不会反思实例的类型,这会(1)变得非常慢,(2)因为各种原因不希望在平等比较。
如果你想要equals()和hashCode()实际上比较值相等(而不是==
所做的引用相等),你需要在你自己的类型中实现它们。
请注意,仅仅实施equals()
是不够的;虽然技术上会“有效”,但它有可能导致各种怪异。简单的经验法则是:既不是,也不是两者,但绝不仅仅是一个。他们必须在同一领域工作;如果equals()
表示两个实例相等,则在上调用hashCode()
必须返回相同的值(另请参阅hashCode()
contract)。
使用代码覆盖toString()
通常也是一个好主意,以提供有问题的对象的有意义的描述。虽然不是严格需要的,但您只需要在调试器中对此进行一次实现以实现该值。 (感谢@JonTaylor提到这个非常有用的相关小故事。)
它的.NET称之为GetHashCode()
,而Java仅使用hashCode()
作为函数名称...
答案 1 :(得分:4)
您需要覆盖equals
课程中的Cat
。默认等于比较引用上的对象。
class Cat {
private String name;
public Cat(String name) {
this.name = name;
}
@Override
public boolean equals(Object obj) {
if (obj == null)
return false;
if (!(obj instanceof Cat))
return false;
Cat c = (Cat) obj;
return this.name == null ? false : this.name.equals(c.name);
}
@Override
public int hashCode() {
return this.name == null ? 31 : this.name.hashCode();
}
@Override
public String toString() {
return "Cat Name :" + name;
}
}
参考
答案 2 :(得分:0)
java.lang.object提供的equals()
简单地比较了对象的唯一标识符,虽然不完全准确,但您可以将其视为内存位置,所以只有你才会这样做将对象与自身进行比较(即对内存中同一对象的两次引用)
您需要在Cat类中实现自己的equals()方法:
class Cat
{
String name;
@Override
public boolean equals(Cat other)
{
if (this.name.equals(other.name))
return true;
return false;
}
}
明智地覆盖hashCode()
,除非这只是一个非常基本的家庭作业应用程序。此外,toString()
也可用于覆盖。
http://docs.oracle.com/javase/tutorial/java/IandI/objectclass.html
答案 3 :(得分:0)
这是因为==
比较引用,而java.lang.Object.equals()
转换为this==o
,因此在您的情况下返回与==
相同
在上面的例子中,您使用new运算符创建两个不同的对象,因此都返回false。
如果您希望.equals()
按预期工作,请覆盖equals()
课程中的Cat
。
答案 4 :(得分:0)
类Object的equals方法实现最具辨别力 对象可能的等价关系;也就是说,对于任何非null 参考值x和y, 当且仅当x时,此方法返回true 和y引用相同的对象 (x == y的值为true)。
如果不重写equals()方法,则对象是不同的 因此
System.out.println(cat1.equals(cat2)); // is false