views:

308

answers:

9

How do I implement this equality comparison is a sane java way?

boolean x = (a == b) || (a.equals(b))

I want to make sure the content of both objects is equal but null is also ok, i.e. both can be null and are thus equal.

Update: just to be clear, I have to implement this comparison several times and don't want to copy&paste this stuff every time, especially with lenghty object names. With 'a' and 'b' it looks small and simple, but tends to grow... I'd like to know if I'm missing some existing Java feature for this.

+5  A: 

What happens if a is null but b is not? I think you really want:

boolean x = (a == null && b == null) || (a != null && a.equals(b))

EDIT: You could implement a static NullEquals method for the class that takes two objects of that class and does the comparison as above to avoid rewriting and make the code a little cleaner.

public class MyClass {

    public static boolean NullEquals( MyClass a, MyClass b )
    {
         return (a == null && b == null) || (a != null && a.equals(b));
    }
}


if (MyClass.NullEquals(a,b))
{
    ...
}
tvanfosson
Thanks for the correction
rassie
but if a is null and b is not, you will get a nullpointer as well
Tobias Schulte
+5  A: 

The typical pattern is:

if (a == b)
{
    return true;
}
if (a == null || b == null)
{
    return false;
}
// Now deal with a and b, knowing that they are non-identical, non-null references

Yes, it's wordy - but if you separate it out into its own method, you can keep it under reasonable control.

Jon Skeet
+9  A: 

You might want to have a look at the always useful Apache Commons Lang, more precisely ObjectUtils.equals().

Guillaume
+8  A: 

Another way to do

boolean x = null==a ? null==b : a.equals(b);
Dennis Cheung
I like this -- wrapped suitably in a method -- except I detest the style of comparing the constant to a variable rather than the other way around. Surely it's not necessary in Java.
tvanfosson
It's useful when comparing a String reference to a literal when the reference might be null, i.e., "text".equals(str). Otherwise, it's just an affectation.
Alan Moore
It's still relevant is a or b is of type boolean or, since 1.5, Boolean. I only do it for literal strings.
Tom Hawtin - tackline
+1. This is the idiom I use (except with `== null`, not `null ==`). Dragging in a filthy library like Apache Commons for a triviality like this is not necessary or desirable.
erickson
+1  A: 

Not a direct answer, but if you have lot of objects that can be or not null, may be that indicates some problem with your code. Take a look at the Null Pattern , that is an alternative way to represent the absence of an object

ljorquera
A: 

Can not add comment, Treat this as comment to Jon Skeet's answer.

Does Null = Null true or false in Java.

More specifically what should be Null = Null should be treated and How and why the different language treat this case ?

Biswanath
Java treats two nulls as being equal, so typically an equality checker should do the same.
Jon Skeet
A: 

The most common way of doing it is:

a==null ? b==null : a.equals(b)

A potentially slightly more efficient, but less clear, expressions is:

a==b || (a!=null && a.equals(b))

You can of course put this inside a method:

public static boolean eq(Object a, Object b) {
     return a==b || (a!=null && a.equals(b));
}

Note the original question code NPEs if a is null and b is non-null.

Tom Hawtin - tackline
A: 

For performance reasons, usually it is good to check for identity before executing any other logic, as was done in the question. However, many of the answers don't take this into account.

The best place to put the identity check is in the implementation of the equals method on your class:

public boolean equals(Object obj) {
  if(this == obj) return true;
  ...
}

If this has/can be done, you can do the comparison easily:

a == null ? b == null : a.equals(b);

Otherwise you might have to check for identity yourself:

a == null ? b == null : (a == b || a.equals(b));
ykaganovich
+1  A: 

What about:

boolean x = equals( a, b );

public static boolean equals( Object a, Object b ) {
    if ( a == null && a == b ) {
        return true;
    } else {
        return a == b || a.equals( b );
    }
}

Let me see.

  • if a is null and a is b then it's ok
  • if a is not null then if a == b ( same ref ) return true by shortcircuit
  • if a is not b ( 2dns part of the OR probably b is null ) then return a ( not null ) .equals( b ) whatever b is

Yeap covered.

OscarRyz