1

I have a java class which is something like this:

class MyClass {

    MyClass(Object obj) {

        m_Obj = obj
    }

    private Object m_Obj;
}

Because m_Obj could be null, my equals method has to look like this:

@Override
public boolean equals(
        Object obj) {

    if (!(obj instanceof MyObject))
        return false;

    MyObject other = (MyObject)obj;

    if ((m_Obj == null) &&
        (other.m_Obj == null)
        return true;

    if ((m_Obj == null) &&
        (other.m_Obj != null)
        return false;

    if ((m_Obj != null) &&
        (other.m_Obj == null)
        return false;


    return m_Obj.equals(other.m_Obj);
}

When I have multiple members of the class which may or may not be null, the equals function just becomes a long slog. I could write my own function:

public boolean equals(
        Object a,
        Object b) {

    if ((a == null) &&
        (b == null)
        return true;

    if ((a == null) &&
        (b != null)
        return false;

    if ((a != null) &&
        (b == null)
        return false;


    return a.equals(b);
}

I'm wondering if someone has already done this in one of the java/apache libraries?

2
  • A minor improvement is that after the initial check to see if both are null, you don't have to check if one is null and the other is not, because you know that the other is not. IE if(a == null && b == null) return true; if(a == null || b == null) return false; return a.equals(b);
    – Egg
    Commented Apr 23, 2015 at 13:32
  • 2
    From Java 7 on: Have a look at Objects.equals. Commented Apr 23, 2015 at 13:33

2 Answers 2

4

Yes, since Java SE 7 there is a standard API for this: Objects.equals

@Override
public boolean equals(Object obj) {

    if (obj == this){
       return true;
    }

    if (!(obj instanceof MyObject))
        return false;

    MyObject other = (MyObject)obj;

    return Objects.equals(m_ObjA, other.m_ObjA)
           && Objects.equals(m_ObjB, other.m_ObjB)
           && (myPrimitive == other.myPrimitive);
}
0
0

Here's my answer to this: (http://sourceforge.net/p/tus/code/HEAD/tree/tjacobs/util/PrimaryKey.java)

package tjacobs.util;

/**
 * The reason d'etre for PrimaryKey is to make overriding equals, hashCode, and compareTo simpler and easier to
 * implement so that they are consistent with one another in data object classes.
 * @author tom_jacobs
 *
 * @param <T>
 */
public interface PrimaryKey<T> {
    public Object[] getPrimaryKey();
    public boolean equals(T obj);
    public int hashCode();

    public interface ComparablePrimaryKey<T> extends Comparable<T>, PrimaryKey<T> {
        @SuppressWarnings("unchecked")
        public Comparable[] getPrimaryKey();

    }

    public static class Impl {
        @SuppressWarnings("unchecked")
        public static final boolean equalsImpl(PrimaryKey key1, PrimaryKey key2) {
            Object[] data1 = key1.getPrimaryKey();
            Object[] data2 = key2.getPrimaryKey();
            //don't check length equal - let that get thrown as an exception
            try {
                for (int i = 0; i < data1.length; i++) {
                    if (data1[i] == null && data2[i] == null) continue;
                    if (data1[i] == null || data2[i] == null) return false;
                    if (!data1[i].equals(data2[i])) return false;
                }
            }
            catch (ArrayIndexOutOfBoundsException ex) {
                //throw new Error("Class: " + key1.getClass() + " has invalid implementation of getPrimaryKey");
                ex.printStackTrace();
                return false;
            }
            return true;
        }

        @SuppressWarnings("unchecked")
        public static final int compareTo(ComparablePrimaryKey key1, ComparablePrimaryKey key2) {
            Comparable[] data1 = key1.getPrimaryKey();
            Comparable[] data2 = key2.getPrimaryKey();
            for (int i = 0; i < data1.length; i++) {
                System.out.println("comparing: " + data1[i] + " to " + data2[i]);
                int compare = data1[i].compareTo(data2[i]);
                if (compare != 0) {
                    System.out.println("returning: " + compare);
                    return compare;
                }
            }
            return 0;
        }

        @SuppressWarnings("unchecked")
        public static final int hashCode(PrimaryKey key) {
            Object[] data1 = key.getPrimaryKey();
            long hashCode = 0;
            for (int i= 0; i < data1.length; i++) {
                hashCode += data1[i].hashCode();
            }
            return (int) hashCode;
        }

        /*
         * model equals, hashCode, compareTo methods

        public boolean equals(Object o) {
            if (o.getClass() != getClass()) {
                return false;
            }
            return PrimaryKey.Impl.equalsImpl( this, o);
        }

        public int hashCode() {
            return PrimaryKey.Impl.hashCode(this);
        }

         public int compareTo(PrimaryKey obj) {
            return PrimaryKey.Impl.compareTo(this, obj);
         }

        */

    }


}

Not the answer you're looking for? Browse other questions tagged or ask your own question.