.equals()用于Java中的用户定义类

时间:2012-10-19 10:29:57

标签: java equals user-defined

请参阅以下代码

class TestToString 
{
  public static void main(String args[]) 
  {
    CheckToString cs = new CheckToString (2);
    CheckToString c = new CheckToString (2);
    if( cs.equals(c))
       System.out.println(" Both objects are equal");
    else
       System.out.println(" Unequal objects ");
  }
}

class CheckToString 
{
   int i;
   CheckToString () 
   {
      i=10;
   }
   CheckToString (int a) 
   {
     this.i=a;
   }
}

输出: 不平等的对象

但我期待输出

两个对象相等

我知道两个对象都有不同的反思,

System.out.println(cs); //com.sample.personal.checkToString@19821f
System.out.println(c); //com.sample.personal.checkToString@addbf1

但我问,为什么他们有不同的推荐? 而在下面的例子中,对象具有相同的内存位置。

Integer a = new Integer(2);
Integer b = new Integer(2);
System.out.println(a);           //2
System.out.println(b);           //2

我将用户定义类的对象与预定义类的对象进行比较。 似乎用户定义类的对象与Integer类的对象的行为相同,其值超过-128到127.为什么这两种情况的引用都不同? (对于Integer类,其值在-128到127之间,对于用户定义的类不同)

6 个答案:

答案 0 :(得分:6)

equals的默认实现检查引用。您正在创建2个不同的对象,它们不会在内存中引用相同的内容。

平等的良好实现将是:

public boolean equals(Object o) {
  if (!(o instanceof CheckToString)) {
    return false;
  }
  CheckToString other = (CheckToString) o;
  return i == other.i;
}

覆盖equals时,您还需要覆盖hashCode

每当你说new CheckToString()时,你在内存中创建一个新对象,所以与另一个new CheckToString()完全不同。对象定义中的内容无关紧要。

你提到的有关Integer的内容是正确的,但它适用于Integer,而不适用于您创建的自定义对象。

答案 1 :(得分:3)

您需要覆盖equals课程中的CheckToString方法:

@Override
public boolean equals(Object o){
   if(this==o){
      return true;
   }
   if(o instanceof CheckString){
       CheckString other = (CheckString) o;
       return this.i == other.i;
   }
   return false;
}

建议您覆盖equals时覆盖hashCode,以便在散列集合中使用对象(即HasSet,LinkedHasSet,HashMap)。在这种情况下,因为你的类似乎是原始整数的包装器,我想你可以返回整数本身。

@Override
public int hashCode(){
   return i;
}

最后,我们总是建议覆盖toString,这样每次查看课程实例时,都会看到对象的友好,人类可读的表示形式。

@Override
public String toString(){
   StringBuilder sb = new StringBuilder();
   sb.append(this.getClass().getSimpleName()).append("[");
   sb.append("i: ").append(i).append("]");
   return sb.toString();
}

答案 2 :(得分:0)

你必须定义自己的toString方法,以返回i和你自己的等于方法的值。

class checkToString
{
   int i;
   public checkToString()
   {
      i=10;
   }
   public checkToString(int a)
   {
     this.i=a;
   }

   public String toString(){ return "" + i;}
   public boolean equals(checkToString a){ return a.toString().equals(this.toString());} 
}

立即尝试。这也可以在没有toString()的情况下完成。

像这样:

public boolean equals(checkToString a){ return (this.i == a.i); }

答案 3 :(得分:0)

默认情况下,equals方法仅检查任何两个对象的哈希码。因此,如果您需要equals方法,则应根据对象中的任何基础属性返回结果,您必须相应地重写equals方法。

答案 4 :(得分:0)

2个对象显然没有指向同一个内存位置(请注意,您正在比较对象引用)。有关详细信息,请参阅对象类的JavaDoc和相应的equals()方法

要比较它们的字符串表示形式,您可以进行以下修改:

class TestToString
 {
  public static void main(String args[])
   {
    CheckToString cs = new CheckToString(2);
    CheckToString c = new CheckToString(2);
    if( cs.toString().equalsIgnoreCase(c.toString()))
       System.out.println(" Both objects are equal");
    else
       System.out.println(" Unequal objects ");
 }
}


class CheckToString
{
   int i;
   CheckToString()
   {
      i=10;
   }
   CheckToString(int a)
   {
     this.i=a;
   }
   public String toString(){
    return String.valueOf(i);
   }
}

ps:还要注意对象案例(Java Conventions

的变化

答案 5 :(得分:0)

equals方法在任何用户定义类中默认基于引用进行比较,但是如果你在当前类中重写equals方法,那么它是基于内容的比较...但是在java.lang.StringClass中它总是基于内容进行比较