9

I have two multidimensional arrays (well actually they're only 2D) which have inferred size. How do I deep clone them? Here's what I have gotten so far:

public foo(Character[][] original){
    clone = new Character[original.length][];
    for(int i = 0; i < original.length; i++)
          clone[i] = (Character[]) original[i].clone();
}

A test for equality original.equals(clone); spits out a false. Why? :|

JasonMArcher
  • 14,195
  • 22
  • 56
  • 52

6 Answers6

13
/**Creates an independent copy(clone) of the boolean array.
 * @param array The array to be cloned.
 * @return An independent 'deep' structure clone of the array.
 */
public static boolean[][] clone2DArray(boolean[][] array) {
    int rows=array.length ;
    //int rowIs=array[0].length ;

    //clone the 'shallow' structure of array
    boolean[][] newArray =(boolean[][]) array.clone();
    //clone the 'deep' structure of array
    for(int row=0;row<rows;row++){
        newArray[row]=(boolean[]) array[row].clone();
    }

    return newArray;
}
Michael Myers
  • 188,989
  • 46
  • 291
  • 292
3

You might want to check out the java.util.Arrays.deepEquals and java.util.Arrays.equals methods.

I'm afraid the equals method for array objects performs a shallow comparison, and does not properly (at least for this case) compare the inner Character arrays.

abahgat
  • 13,360
  • 9
  • 35
  • 42
3

equals() method on arrays is the one declared in Object class. This means that it will only returns true if the object are the same. By the same it means not the same in CONTENT, but the same in MEMORY. Thus equals() on your arrays will never return true as you're duplicating the structure in memory.

gizmo
  • 11,819
  • 6
  • 44
  • 61
1

A test for equality original.equals(clone); spits out a false. Why? :|

thats because you are creating a new array with new Character[original.length][];.

Arrays.deepEquals(original,clone) should return true.

Andreas Petersson
  • 16,248
  • 11
  • 59
  • 91
0

Same as @Barak solution (Serialize and Deserialize) with examples (as some people could not understand and down voted that)

public static <T extends Serializable> T deepCopy(T obj)
{
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    try
    {
        ObjectOutputStream oos = new ObjectOutputStream(baos);

        // Beware, this can throw java.io.NotSerializableException 
        // if any object inside obj is not Serializable
        oos.writeObject(obj);  
        ObjectInputStream ois = new ObjectInputStream(
                                    new ByteArrayInputStream(baos.toByteArray()));
        return (T) ois.readObject();
    }
    catch (  ClassNotFoundException /* Not sure */
           | IOException /* Never happens as we are not writing to disc */ e)
    {
        throw new RuntimeException(e); // Your own custom exception
    }
}

Usage:

    int[][] intArr = { { 1 } };
    System.out.println(Arrays.deepToString(intArr)); // prints: [[1]]
    int[][] intDc = deepCopy(intArr);
    intDc[0][0] = 2;
    System.out.println(Arrays.deepToString(intArr)); // prints: [[1]]
    System.out.println(Arrays.deepToString(intDc)); // prints: [[2]]
    int[][] intClone = intArr.clone();
    intClone[0][0] = 4;

    // original array modified because builtin cloning is shallow 
    System.out.println(Arrays.deepToString(intArr)); // prints: [[4]]
    System.out.println(Arrays.deepToString(intClone)); // prints: [[4]]

    short[][][] shortArr = { { { 2 } } };
    System.out.println(Arrays.deepToString(shortArr)); // prints: [[[2]]]

    // deepCopy() works for any type of array of any dimension
    short[][][] shortDc = deepCopy(shortArr);
    shortDc[0][0][0] = 4;
    System.out.println(Arrays.deepToString(shortArr)); // prints: [[[2]]]
    System.out.println(Arrays.deepToString(shortDc)); // prints: [[[4]]]
Venkata Raju
  • 4,866
  • 3
  • 27
  • 36
-1

I found this answer for cloning multidimensional arrays on jGuru:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(this);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
Object deepCopy = ois.readObject();
Barak Schiller
  • 1,066
  • 9
  • 9