How to check if 2 Class instances are the same

20,437

Solution 1

You should have included your Fruit class, but here is one way

static class Fruit {
  private String name;

  public Fruit(String name) {
    this.name = name;
  }

  @Override
  public boolean equals(Object otherObject) {
    // check for reference equality.
    if (this == otherObject) {
      return true;
    }
    if (otherObject instanceof Fruit) {
      Fruit that = (Fruit) otherObject;
      // Check for name equality.
      return (name == null && that.name == null)
          || name.equals(that.name);
    }
    return false;
  }
}

public static void main(String[] args) {
  Fruit apple = new Fruit("apple");
  Fruit apple2 = new Fruit("apple");

  Fruit orange = new Fruit("orange");

  if (apple.equals(orange))
    System.out.println("true");
  else
    System.out.println("false");

  // You can also use the shorter
  System.out.println(apple.equals(apple2));
}

Outputs

false
true

Solution 2

As Java uses implicit references you need to make a difference between object euqality and reference euqality.

If you just want to know wether two objects denode the same memory cell, so they are really the same, you cann use the equals operator:

Object A = new Fruit("A");
Object B = new Fruit("A");
System.out.println(A == B);

This would print false, as A and B are not the same reference cell.

Object A = new Fruit("A");
Object B = A
System.out.println(A == B);

Would return true, as they both are "pointers" to the same reference cell.

If you want to achieve semantic equality, I would advise you to make use of the equals method AND the fields of the class.

Object A = new Fruit("A");
Object B = new Fruit("A");
System.out.println(A.equals(B));

should return true in this case.

To achieve this you can usethe following equals method for every possible class you could write: (assuming you have getter and setter for the field A and your class is named myClass)

public boolean equals(Object B){
if(B instanceof MyClass){
  MyClass B = (MyClass) B;
  boolean flag = this.getA().equals(B.getA());
  return flag;
}
  return false;
}

You would have to do the boolean flag = this.getA().equals(B.getA()); for every field of the class. This would lead to equality if the objects fields have the same values.

But oyu have to keep in mind, that there is no perfect equals method. There is the so called hashcode equals contract in java which means that A.equals(B) has to hold, whenever A.hashCode()==B.hashCode()

A nice thing of the flag approach is that you don't have to care about the types of the objects fields, as for Basic Types that are not Objects (int, float, ...) the Java Runtime will do implicit bocing and cast them to Integer or Float Objects and use the equals method of them.

Share:
20,437
kar
Author by

kar

13 years experience in the marine and shipping field mainly related to electronics engineering . Switched field and started fresh to pursue an interest in programming and currently working as a Software Engineer in casino gaming sector.

Updated on July 22, 2022

Comments

  • kar
    kar almost 2 years

    For example I have a class Fruit. I create 2 instances:

    Fruit apple = new Fruit("apple");
    Fruit orange = new Fruit("orange");
    

    The value of the 2 instances are not the same thus I am looking for the answer to be false. I override the .equals() method and wrote the following method to do the test:

    @Override
    public boolean equals(Object otherObject){
        if(otherObject instanceof Fruit){ 
            return true;
        }
        return false; 
    }
    
        if(apple.equals(orange))
            System.out.println("true"); 
        else
            System.out.println("false");
    

    The above method gives me the answer as true. From my understanding, this is a correct response since this simply tests if they both belongs to the same Class which is true.

    But I can't get around to testing the values of the instances itself. Please advice. Thanks.

  • Pshemo
    Pshemo about 10 years
    +1 but why not just System.out.println(apple.equals(apple2)) instead of ifs?
  • Elliott Frisch
    Elliott Frisch about 10 years
    @Pshemo The same could be done with the apple.equals(orange) but I agree that improves the answer; edited.
  • kar
    kar about 10 years
    It works if there is only one parameter thus easy to make a comparison between names. What if it has multiple parameters? Only solution is to individual match each and every parameter to check? Tnks.
  • Elliott Frisch
    Elliott Frisch about 10 years
    @keshk If by "parameter" you mean instance member and that the objects should not be "equal" if those instance member variables are not equal, then yes. Other choices include using a hashCode (but you still have to check for collisions).