3

可能重复:
为什么 .equals 方法在两个相同的值对象上失败?

这真的很简单,但我显然在这里遗漏了一些非常重要的东西。

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()工作?我的印象是它比较了对象的所有字段。似乎情况并非如此。

我需要为我的所有课程覆盖它吗?

4

5 回答 5

7

是的。

java.lang.Objectequals()提供了和的非常基本的实现hashCode()。特别是,他们不会到处考虑实例的类型,这会 (1) 非常缓慢,并且 (2) 存在比较您出于各种原因不想在平等比较。

如果您希望 equals() 和 hashCode() 实际上对比较值相等有用(而不是引用相等==),您需要在自己的类型中实现两者。

equals()请注意,仅实现;是不够的。虽然从技术上讲这会“起作用”,但它有可能导致各种怪异。简单的经验法则是:两者都不是或两者都不是,但绝不是只有一个。他们必须在相同的领域工作;如果equals()说两个实例相等,则调用hashCode()两者必须返回相同的值(另见hashCode()合同)。

toString()用代码覆盖以提供对相关对象的有意义的描述通常也是一个好主意。虽然不是严格需要,但您只需要在调试器中对此进行一次尝试即可实现该值。(感谢@JonTaylor 提到这个非常有用的相关花絮。)

它是 .NET 调用它GetHashCode(),而 Java 仅用hashCode()作函数名......

于 2012-10-31T19:24:36.220 回答
4

你需要equals在你的Cat类中覆盖。默认 equals 比较引用上的对象。

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;
}
}

参考

于 2012-10-31T19:24:28.353 回答
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

于 2012-10-31T19:28:29.487 回答
0

那是因为== 比较引用并java.lang.Object.equals()转换为this==o因此返回与==您的情况相同

在上述情况下,您使用 new 运算符创建两个不同的对象,因此都返回 false。

如果您想.equals()按预期工作,请覆盖equals()您的Cat班级。

于 2012-10-31T19:32:00.743 回答
0

来自[Java 文档]

Object 类的 equals 方法实现了对象上最有区别的可能等价关系;也就是说,对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象(x == y 的值为 true)时,此方法才返回 true。

在不覆盖 equals() 方法的情况下,对象是不同的因此

 System.out.println(cat1.equals(cat2)); // is false
于 2012-10-31T19:33:14.593 回答