Jyoti Ranjan Pattnaik
Jyoti Ranjan Pattnaik

Reputation: 723

.equals() for user defined class in Java

Please see the below code

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

Output: Unequal objects

But I was expecting the output will be

Both objects are equal

I understood that both the objects have different refferences,

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

but I was asking, why do they have different referrences? whereas in the below case, the objects have same memory locations.

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

I am comparing the object of user-defined class with the object of pre-defined class. It seems the object of user-defined class behaves same as the object of Integer Class having value beyond -128 to 127. Why are the referrences different for both the cases? (same for Integer class having value within -128 to 127 and different for user-defined class)

Upvotes: 3

Views: 6860

Answers (5)

Vivek Bhandari
Vivek Bhandari

Reputation: 1

equals method compare on the basis of reference by default in any user define class but if you override the equals method in the current class then it is compare on the basis of content...but in the java.lang.StringClass it is compare on the basis of content always

Upvotes: -1

Dan D.
Dan D.

Reputation: 32391

The default implementation of equals checks references. You are creating 2 different object, that don't refer the same thing in memory.

A decent implementation of equals would be something like:

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

When overridding equals, you need to override hashCode, too.

Whenever you say new CheckToString(), you are creating a new object in memory, so a totally different reference than another new CheckToString(). It doesn't matter what is inside the object definition.

The stuff you mention about Integer is true, but it applies to Integer, not to a custom object that you have created.

Upvotes: 7

Edwin Dalorzo
Edwin Dalorzo

Reputation: 78629

You need to override the equals method in your CheckToString class:

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

It's recommended that when you override equals you also override hashCode, so that you can use your object in hashed collections (i.e. HasSet, LinkedHasSet, HashMap). In a case like this, since your class appears to be a wrapper over a primitive integer, I guess you could return the integer itself.

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

And finally, it's always recommended to override toString, so that every time you look at instances of your class you see a friendly, human-readable representation of your object.

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

Upvotes: 3

MaVRoSCy
MaVRoSCy

Reputation: 17849

the 2 objects are obviously not pointing in the same memory location (Notice that you are comparing Object References). For more info see JavaDoc of Object Class and the respective equals() methos

To compare their string representation you could do this modification:

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: Note also the change in the Object's Case (Java Conventions)

Upvotes: 0

Sumit Desai
Sumit Desai

Reputation: 1770

By default, equals method only checks the hashcodes of any two objects. So, if you need that equals method should return result depending on any underlying property in your object, you will have to override equals method accordingly.

Upvotes: -1

Related Questions