2

I'm having some trouble with this for some reason.

I have two java Objects, both of which can be anything, including primitive and non-primitive arrays.

I need to perform an equals check.

If they are arrays, then I have to check their contents instead of their runtime instance.

So for example, let's say I have a method as such:

/**
     * Returns true if the two parameters are arrays, and they both contain
     * the same content.
     * @param aObject1 An object
     * @param aObject2 An object
     * @return
     */
    private boolean equalsArray( Object aObject1, Object aObject2 ) {
      if(aObject1==null){
        return false;
      }
      if(aObject2==null){
        return false;
      }
      if(!aObject1.getClass().isArray()){
        return false;
      }
      if(!aObject2.getClass().isArray()){
        return false;
      }
      //How do I check if the two arrays here contain the same objects
      //without knowledge of their type???

    }

Note that the arrays can be anything, and will most likely not be Object[], but rather Foo[] or Bar[].

Any suggestions? I can't do Array.equals(Object[],Object[]) because I can't cast to Object[].

2
  • 1
    Arrays.equals((Object[]) aObject1, (Object[]) aObject2); is the way to go and you can of course cast Object to Object[]. Commented Jul 4, 2011 at 15:37
  • @anubhava if the parms are primitive arrays the cast to Object[] will fail. Commented Jul 4, 2011 at 15:46

5 Answers 5

2

Use java.lang.reflect.Array:

    if (Array.getLength(first) != Array.getLength(second))
        return false;

    for (int i = 0; i < Array.getLength(first); ++i) {
        Object firstItem = Array.get(first, i);
        Object secondItem = Array.get(second, i);
        if (!(firstItem == null ? secondItem == null : firstItem.equals(secondItem)))
            return false;
    }
    return true;
Sign up to request clarification or add additional context in comments.

2 Comments

+1: This is likely to be simplest. It will mean an int[] and Integer[] can be equal.
Or, if you need to handle multi-dimensional arrays correctly, recursively call your method when testing item equality. Or, just use the previously mentioned Commons Lang method.
1

There is a nice equals utility in

boolean org.apache.commons.lang.ArrayUtils.isEquals(Object array1, Object array2)

It will run something like this - which of course you don't want to write manually :-)

public static boolean isEquals(Object array1, Object array2) {
    return new EqualsBuilder().append(array1, array2).isEquals();
}

public EqualsBuilder append(Object lhs, Object rhs) {
    if (isEquals == false) {
        return this;
    }
    if (lhs == rhs) {
        return this;
    }
    if (lhs == null || rhs == null) {
        this.setEquals(false);
        return this;
    }
    Class lhsClass = lhs.getClass();
    if (!lhsClass.isArray()) {
        // The simple case, not an array, just test the element
        isEquals = lhs.equals(rhs);
    } else if (lhs.getClass() != rhs.getClass()) {
        // Here when we compare different dimensions, for example: a boolean[][] to a boolean[] 
        this.setEquals(false);
    }
    // 'Switch' on type of array, to dispatch to the correct handler
    // This handles multi dimensional arrays of the same depth
    else if (lhs instanceof long[]) {
        append((long[]) lhs, (long[]) rhs);
    } else if (lhs instanceof int[]) {
        append((int[]) lhs, (int[]) rhs);
    } else if (lhs instanceof short[]) {
        append((short[]) lhs, (short[]) rhs);
    } else if (lhs instanceof char[]) {
        append((char[]) lhs, (char[]) rhs);
    } else if (lhs instanceof byte[]) {
        append((byte[]) lhs, (byte[]) rhs);
    } else if (lhs instanceof double[]) {
        append((double[]) lhs, (double[]) rhs);
    } else if (lhs instanceof float[]) {
        append((float[]) lhs, (float[]) rhs);
    } else if (lhs instanceof boolean[]) {
        append((boolean[]) lhs, (boolean[]) rhs);
    } else {
        // Not an array of primitives
        append((Object[]) lhs, (Object[]) rhs);
    }
    return this;
}

Comments

0

You may use

  Arrays.equals(Object[] a, Object[] a2)

However you will have to implement the equals for the contents since the method does:

 o1.equals(o2)

This will only work if you implement equals for that object.

For non primitive types there is an

 Arrays.equals

override for every primitive type.

Comments

0

You can use Arrays.equal(..) or, if the arrays can have nested arrays Arrays.deepEquals(..)

3 Comments

No it won't. If you have a class Foo[], then this will throw an exception because it can't case Foo[] to Object[]
@Tovi7: I don't understand your comment: a Foo[] is an Object[]: no need for casting
I have a compile time "Object" which at runtime is "Foo[]". I have to cast to Object[] or the method wont work. If I do cast it to Object[] and execute your methods (like I stated in my original question) I get classcastexceptions in the method.
0

How about:

if(aObject1.getClass().getName().equals(aObject2.getClass().getName()))
return Arrays.equals(aObject1, aObject2);
else return false;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.