问题
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? :|
回答1:
/**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;
}
回答2:
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.
回答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.
回答4:
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.
回答5:
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]]]
回答6:
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();
来源:https://stackoverflow.com/questions/200387/deep-cloning-multidimensional-arrays-in-java