21

I find stuff like this rather annoying and ugly in equals methods:

if (field == null)
{
    if (other.field != null)
        return false;
}
else if ( ! field.equals(other.field))
    return false;

In C# I could've done this:

if( ! Object.Equals(field, other.field))
    return false;

Is there something similar in Java, or what is the preferred way to do this kind if thing?

Svish
  • 152,914
  • 173
  • 462
  • 620
  • 1
    I think you will find this thread useful: http://stackoverflow.com/questions/271526/how-to-avoid-null-statements-in-java – hovanessyan Oct 25 '11 at 13:28
  • Interesting, sure. Useful... personally it mostly just raised more questions :p – Svish Oct 25 '11 at 14:17

9 Answers9

49

Java 7 offers java.util.Objects.equals.

pholser
  • 4,908
  • 1
  • 27
  • 37
25

Use commons-lang:

org.apache.commons.lang.ObjectUtils.equals(Object object1, Object object2)

Source code:

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

From Apache

http://commons.apache.org/lang/

That's about equivalent to what you do in C#

Lukas Eder
  • 211,314
  • 129
  • 689
  • 1,509
  • And if you impor that method statically (import static org.apache.commons.lang.ObjectUtils.equals;) then you can simply write `equals(a,b)` in your code – Óscar López Oct 25 '11 at 13:34
  • Awesome. Didn't know about that class! The `ObjectUtils.hashCode` was also brilliant. – Svish Oct 25 '11 at 13:38
  • 2
    @ÓscarLópez: You can't do that. The compiler won't like it (because of the collision with `Object.equals(Object)`). That's where Guava's `equal()` method is better suited – Lukas Eder Oct 25 '11 at 13:39
  • @Svish: I personally like apache commons. But do also have a look at Google Guava as suggested by NimChimpsky here: http://stackoverflow.com/questions/7889933/how-to-prevent-null-check-before-equals/7889990#7890024 – Lukas Eder Oct 25 '11 at 13:40
  • Just discovered they have a `EqualsBuilder` and `HashCodeBuilder` in there too. Might just start using those... – Svish Oct 25 '11 at 14:16
  • @Stefan, maybe I'm missing something, but my Eclipse compiler will complain – Lukas Eder Oct 25 '11 at 14:18
  • @Lukas Sorry i was too hasty it does indeed complain but I dont understand tho why the compiler wont let you do that after all they have different signatures. Especially since it does not have the problem with static and non static methods with the same name within a class. And i think i actually ran into that problem myself but forgot. – Stefan Oct 25 '11 at 14:18
  • @Stefan: I somewhere read the reason for this in the JLS, but I forgot... Let's ask a question on Stack Overflow :) – Lukas Eder Oct 25 '11 at 14:21
  • @Stefan: here's the question: http://stackoverflow.com/questions/7890853/why-cant-i-static-import-an-equals-method-in-java – Lukas Eder Oct 25 '11 at 14:27
5

Guava equal which does this :

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

or null object pattern

Guava also has the somewhat related comparison chain and a load of other goodies.

Community
  • 1
  • 1
NimChimpsky
  • 46,453
  • 60
  • 198
  • 311
  • 2
    The nice thing about their calling the method `equal` and not `equals` (like commons-lang) is the fact that it can be used in static imports... – Lukas Eder Oct 25 '11 at 13:45
4

I would write it this way:

return field != null && other.field != null && field.equals(other.field);

which is not as elegant as the C# code line, but much shorter then the if tree you posted.

HefferWolf
  • 3,894
  • 1
  • 23
  • 29
2

I accept all answers technically. Practically I will not use any of them in code I have under control because all provided solutions are working around the core problem: null-values. KEEP YOUR CORE MODEL FREE FROM NULL VALUES, and the question is obsolete in this case.

At system borders like third party libraries one has to deal with null values sometimes. They should converted into meaningful values for the core model. There the given solutions are helpful.

Even if Oracle recommends the equals-Methods to be null-safe, think about that: Once you accept null values your model it is getting fragile. The equals-method will not be the last method where you will check for null. You have to manage null-checks in your method call hierarchy. Methods may not be reusable out of the box anymore. Soon, every parameter will be checked for null.

I saw both sides:

On one side code full of null checks, methods that trust not a single parameter anymore and developers that are afraid to forget a null check.

On the other side code with full expressive statements that make clear assertions to have full functioning objects that can be used without fear of NullPointerExceptions.

oopexpert
  • 767
  • 7
  • 12
1

Actually everyone follows there own way to do this and also i would like to introduce groovy here.

There is one way

field == null ? false : true; // So basically it will return true when it is not null.

In groovy there is null safe operator for objects. Lets take an example for class

A { 
 String name = "test1"
String surName = "test2"

public String returnName() {

 return name + surName
}

}

A a = null a?.name // Mentioned operator ? will actually check whether a is null or not. then it will invoke name.

Note: i didn't applied semi colon in code as this is not require in groovy.

Ankur Mahajan
  • 3,396
  • 3
  • 31
  • 42
Ashay Jain
  • 98
  • 6
1

As part of the Project Coin, there was a proposal for adding a series of null-safe operators to Java. Sadly, they didn't make it into Java 7, maybe they'll appear in Java 8. Here is the general idea of how they would work

Óscar López
  • 232,561
  • 37
  • 312
  • 386
0

Use == operator when you are checking for object references, if both the references refers same object it will return true. Otherwise if you are looking for object content then go with .equals method of objects.

So null means it doesn't have any memory location given in heap. So it can be simply checked with '==' operator.

Ankur Mahajan
  • 3,396
  • 3
  • 31
  • 42
0

String.valueOf() will solve some of those problems if the toString is implemented for your classes. It will spit out the toString() answer or "null" if the pointer is null.

Thom
  • 14,013
  • 25
  • 105
  • 185
  • That depends whether you want a field value of `null` to equal one with value "null". I would say in most cases that's *not* desirable. It also depends on your toString matching exactly what's required for equality matching... and it's also likely to be rather slower... – Jon Skeet Oct 25 '11 at 13:29
  • I understand why SQL says that null != null, but I don't always agree with that approach. Frequently, when I'm implementing equals, I'm OK with null == null. I agree with the speed comment, but the author wanted to avoid null checking, so I was answering the question. – Thom Oct 25 '11 at 13:37
  • I'm not talking about `null == null`. I'm talking about `null == "null"`. – Jon Skeet Oct 25 '11 at 13:38
  • If I was needing this for creating strings, then yes :p – Svish Oct 25 '11 at 13:38