Md Irfan Mullick
Md Irfan Mullick

Reputation: 1

How can I avoid multiple if else blocks for Object.equals method?

I'm trying to implement this:

public boolean equals(Object o) {
    if (o == this) {
        return true;
    }
    if ((null == o) || !(o instanceof Document)) {
        return false;
    }
    Document other = (Document) o;
    // compare in a null-safe manner
    if (list == null) {
        if (other.list != null)
            return false;
    } else if (other.list == null)
        return false;
    else if (!(list.size() == other.list.size())
            && !(list.equals(other.list)))
        return false;
    return true;

where 'list' is a class variable as well as a field of the object 'o'. Please note that the object 'o' has many other fields including booleans and collection too and I need to compare all of them. I tried finding related answers but most of them recommend switch cases or other Java 8 components which is not relevant to my scenario.

Upvotes: 0

Views: 457

Answers (2)

maaartinus
maaartinus

Reputation: 46432

You're greatly complicating things. Writing "equals" is lengthy boring boilerplate, but you're making it even longer.

public boolean equals(Object o) {
    if (o == this) {
        return true;
    }
    if (!(o instanceof Document)) {
        return false;
    }
    Document other = (Document) o;
    if (!Objects.equals(list, other.list)) {
        return false;
    }
    return true;
}

All you need per reference field are the three lines above, similarly for primitives (don't forget to handle NaN for floating point).

Your condition is not only much longer, but it also lacks symmetry. This makes it much harder to write and more error-prone.

Anyway, writing "equals" is not something you should do often manually. I recommend using Lombok and there are many more tools, e.g., AutoValue or EqualsBuilder.

Upvotes: 1

Stephen C
Stephen C

Reputation: 718926

A direct rewrite would be:

// compare in a null-safe manner
if (list == null || other.list == null) {
    return list == other.list;
} else {
    return list.size() == other.list.size() ||
           list.equals(other.list));
}

except if the type of list is a standard Java SE List class you can do away with the size() micro-optimization. (A typical `List.equals implementation will do that for you.) So we can rewrite the above as

// compare in a null-safe manner
if (list == null || other.list == null) {
    return list == other.list;
} else {
    return list.equals(other.list));
}

except that that is what Objects.equals(...) does. So the final rewrite is:

// compare in a null-safe manner
return Objects.equals(list, other.list);

It is unclear if an IDE will generate equals methods test the fields in a null-safe way. But the counterpoint to that is that it is advisable to design your classes so that you don't need to do that. For example, use an empty List rather than a null.

Upvotes: 0

Related Questions