8

サイズが推定される 2 つの多次元配列 (実際には 2D のみ) があります。それらをディープクローンするにはどうすればよいですか? これが私がこれまでに得たものです:

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

等しいかどうかのテストoriginal.equals(clone);は false を吐き出します。なんで?:|

4

6 に答える 6

3

配列の equals() メソッドは、Object クラスで宣言されたものです。これは、オブジェクトが同じ場合にのみ true を返すことを意味します。同じということは、CONTENT では同じではなく、MEMORY では同じことを意味します。したがって、メモリ内の構造を複製しているため、配列の equals() は決して true を返しません。

于 2008-10-14T09:00:31.043 に答える
3

java.util.Arrays.deepEqualsおよびjava.util.Arrays.equalsメソッドを確認することをお勧めします。

残念ながらequals、配列オブジェクトのメソッドは浅い比較を実行し、(少なくともこの場合は) 内部Character配列を適切に比較しません。

于 2008-10-14T08:48:30.537 に答える
1

等しいかどうかのテスト original.equals(clone); 嘘を吐く。なんで?:|

で新しい配列を作成しているためですnew Character[original.length][];

Arrays.deepEquals(original,clone)true を返す必要があります。

于 2008-10-14T09:00:33.320 に答える
0

@Barak ソリューション (Serialize および Deserialize) と同じ例を示します (一部の人々は理解できず、反対票を投じたため)

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
    }
}

使用法:

    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]]]
于 2014-08-07T17:47:03.770 に答える
-1

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();
于 2008-10-14T09:23:50.480 に答える