How to compare two java objects

185,150

Solution 1

You need to provide your own implementation of equals() in MyClass.

@Override
public boolean equals(Object other) {
    if (!(other instanceof MyClass)) {
        return false;
    }

    MyClass that = (MyClass) other;

    // Custom equality check here.
    return this.field1.equals(that.field1)
        && this.field2.equals(that.field2);
}

You should also override hashCode() if there's any chance of your objects being used in a hash table. A reasonable implementation would be to combine the hash codes of the object's fields with something like:

@Override
public int hashCode() {
    int hashCode = 1;

    hashCode = hashCode * 37 + this.field1.hashCode();
    hashCode = hashCode * 37 + this.field2.hashCode();

    return hashCode;
}

See this question for more details on implementing a hash function.

Solution 2

You need to Override equals and hashCode.
equals will compare the objects for equality according to the properties you need and hashCode is mandatory in order for your objects to be used correctly in Collections and Maps

Solution 3

You need to implement the equals() method in your MyClass.

The reason that == didn't work is this is checking that they refer to the same instance. Since you did new for each, each one is a different instance.

The reason that equals() didn't work is because you didn't implement it yourself yet. I believe it's default behavior is the same thing as ==.

Note that you should also implement hashcode() if you're going to implement equals() because a lot of java.util Collections expect that.

Solution 4

You have to correctly override method equals() from class Object

Edit: I think that my first response was misunderstood probably because I was not too precise. So I decided to to add more explanations.

Why do you have to override equals()? Well, because this is in the domain of a developer to decide what does it mean for two objects to be equal. Reference equality is not enough for most of the cases.

For example, imagine that you have a HashMap whose keys are of type Person. Each person has name and address. Now, you want to find detailed bean using the key. The problem is, that you usually are not able to create an instance with the same reference as the one in the map. What you do is to create another instance of class Person. Clearly, operator == will not work here and you have to use equals().

But now, we come to another problem. Let's imagine that your collection is very large and you want to execute a search. The naive implementation would compare your key object with every instance in a map using equals(). That, however, would be very expansive. And here comes the hashCode(). As others pointed out, hashcode is a single number that does not have to be unique. The important requirement is that whenever equals() gives true for two objects, hashCode() must return the same value for both of them. The inverse implication does not hold, which is a good thing, because hashcode separates our keys into kind of buckets. We have a small number of instances of class Person in a single bucket. When we execute a search, the algorithm can jump right away to a correct bucket and only now execute equals for each instance. The implementation for hashCode() therefore must distribute objects as evenly as possible across buckets.

There is one more point. Some collections require a proper implementation of a hashCode() method in classes that are used as keys not only for performance reasons. The examples are: HashSet and LinkedHashSet. If they don’t override hashCode(), the default Object hashCode() method will allow multiple objects that you might consider "meaningfully equal" to be added to your "no duplicates allowed" set.

Some of the collections that use hashCode()

  • HashSet
  • LinkedHashSet
  • HashMap

Have a look at those two classes from apache commons that will allow you to implement equals() and hashCode() easily

Solution 5

1) == evaluates reference equality in this case
2) im not too sure about the equals, but why not simply overriding the compare method and plant it inside MyClass?

Share:
185,150
Roy Hinkley
Author by

Roy Hinkley

Updated on December 17, 2020

Comments

  • Roy Hinkley
    Roy Hinkley over 3 years

    I have two java objects that are instantiated from the same class.

    MyClass myClass1 = new MyClass();
    MyClass myClass2 = new MyClass();
    

    If I set both of their properties to the exact same values and then verify that they are the same

    if(myClass1 == myClass2){
       // objects match
       ...
    
    }
    
    if(myClass1.equals(myClass2)){
       // objects match
       ...
    
    }
    

    However, neither of these approaches return a true value. I have checked the properties of each and they match.

    How do I compare these two objects to verify that they are identical?

  • afsantos
    afsantos about 11 years
    @Aubin Usually, prime numbers are used in hash code generation. If I'm not mistaken, it reduces the chances that there will be collisions on the generated hashes. As to why use 37, I guess it is just a popular choice, I don't know of any particular reason for using 37 instead of, say, 13.
  • Roy Hinkley
    Roy Hinkley about 11 years
    Thank you - all really. Everyone put me on the right path, but I can only accept one as correct.
  • afsantos
    afsantos about 11 years
    @John Your equals could also check for other == this, although this is not necessary, it would return true without verifying each field.
  • Arthur Eirich
    Arthur Eirich over 9 years
    shouldn't hashCode be a non zero int after creating it?
  • Arthur Eirich
    Arthur Eirich over 9 years
    @JohnKugelman According to the "reasonable implementation" provided in your answer the first rule says that the initial hashCode value should be a non zero int. Do I understand something wrong?
  • John Kugelman
    John Kugelman over 9 years
    @ArthurEirich I see now. No, you're right, I've updated my answer to match the link.
  • thomas.mc.work
    thomas.mc.work over 8 years
    Wouldn't it be sufficient to compare the respective hashCodes of the two objects? (assuming the hashCode() method has been implemented)
  • John Kugelman
    John Kugelman over 8 years
    @thomas.mc.work No. If the hash codes are different you know the objects are different, but if the hash codes are the same you don't know the objects are equal. Unequal objects can have the same hash code. Indeed by the pigeonhole principle this is generally unavoidable. There are only 2^32 hash codes but an infinite number of Strings, for instance.
  • Tom O.
    Tom O. over 7 years
    Nice explanation. Short and to the point.
  • Tiina
    Tiina over 6 years
    @Aubin I think 37 is from Monte Carlo tests, and the same tests on String shows that 31 is also acceptable and its less complicated, so 31 is used for java String hashCode. This is shown in Figure 5.45 in Data structures and Algorithm analysis. A clear figure could be found at faculty.cs.uwlax.edu/~mallen/courses/cs340/lec16.pdf