K''
K''

Reputation: 5238

override equals method to compare more than one field in java

What is the best way to override equals method in java to compare more than one field? For example, I have 4 objects in the class, o1, o2, o3, o4 and I want compare all of them with the passed object to the equals method.

if (o1 != null && o2 != null && o3 != null && o4 != null && obj.o1 != null
    && obj.o2 != null && obj.o3 != null && obj.o4 != null
    && o1.equals(obj.o1) && o2.equals(obj.o2) && o3.equals(obj.o3) && o4.equals(obj.o4)) {
    do something
}

The problem with this code is that it's not clear and can't be modified easily specially if we have more fields. Is there a better way to achieve that?

Upvotes: 3

Views: 4346

Answers (6)

JPM
JPM

Reputation: 9296

I've run into this a few times and the easiest way I did this was to put all the compared Objects into a LinkedList and then write a customer comparer method for your Object that will take in that list and run through it to find out if they are equal to the passed object. You might even find that LinkedList method 'contains()' will do this for you, depending on your Objects.

Upvotes: 0

Ryan Stewart
Ryan Stewart

Reputation: 128899

Use Guava:

@Override
public boolean equals(final Object obj){
    if (!(obj instanceof Foo)) {
        return false;
    }
    final Foo other = (Foo) obj;
    return Objects.equal(o1, other.o1)
        && Objects.equal(o2, other.o2)
        && Objects.equal(o3, other.o3)
        && Objects.equal(o4, other.o4);
}

You get hashCode() for cheap, too:

@Override
public int hashCode() {
    return Objects.hashCode(o1, o2, o3, o4);
}

Upvotes: 5

Tom
Tom

Reputation: 44871

If using one let you ide create it for you.

Upvotes: 0

corsiKa
corsiKa

Reputation: 82589

Use a utility method to help you

private static boolean nullSafeEquals(Object o1, Object o2) {
    if(o1 == null && o2 == null) return true; // both null, both equal
    if(o1 == null || o2 == null) return false; // if one is null, not equal - we know both won't be null
    return o1.equals(o2);
}

public boolean equals(Object o) {
    if(o instanceof ThisClass) {
        ThisClass tc = (ThisClass)o;
        return nullSafeEquals(o1, tc.o1)
            && nullSafeEquals(o2, tc.o2)
            && nullSafeEquals(o3, tc.o3)
            && nullSafeEquals(o4, tc.o4);
    }
    return false;
}

Upvotes: 5

Jon Skeet
Jon Skeet

Reputation: 1502076

One thing is to have a helper method in a utility class:

public static boolean equals(Object o1, Object o2)
{
     if (o1 == o2)
     {
         return true;
     }
     if (o1 == null || o2 == null)
     {
         return false;
     }
     return o1.equals(o2);
}

Then you can write:

public boolean equals(Object other)
{
    if (other == null || this.getClass() != other.getClass())
    {
        return false;
    }
    Foo x = (Foo) other;
    return Helper.equals(o1, x.o1) &&
           Helper.equals(o2, x.o2) &&
           Helper.equals(o3, x.o3) &&
           Helper.equals(o4, x.o4);
}

Note that this way it also copes when two fields are both null, which the code in the question doesn't. (I say "copes" - it gives a result which is more consistent with the rest of Java.)

You can create a similar helper method for hashCode too.

Note that Guava already supports this in its Objects class (and I'm sure many other utility libraries do too).

Upvotes: 9

Mark Peters
Mark Peters

Reputation: 81104

A cheap way would be to do:

Arrays.asList(o1, o2, o3, o4).equals(Arrays.asList(obj.o1, obj.o2, obj.o3, obj.o4));

Upvotes: 11

Related Questions