簡體   English   中英

克隆多維數組

[英]Cloning multi-dimensional arrays

int[][] array = new int[][] {...}
int[][] clone = array.clone();

我天真地期待這個工作。 但它沒有 - 它只克隆了第一個維度,如果我想要一個真正的克隆,我必須手動克隆另一個維度。 注意:內容已正確復制。 但是當我改變了clone[0][1] ,它反映在array[0][1]

雖然已知.clone()執行淺層克隆,但int[][]看起來像一個單獨的對象(如果我們不知道它的內部實現,至少)

為什么選擇這種行為? 是不是int[][]引用數組對象,而不僅僅是數組的第一個維度? 在什么情況下只克隆第一個維度所需的行為?

為什么選擇這種行為?

一致性,最有可能。

如你所說, int[][]引用一個數組對象。 碰巧每個數組元素的內容都是另一個數組,但這只是一個細節。 Java以相同方式克隆所有數組,並且由於元素可以是任何類型,因此無法保證執行深層復制。

因此,數組的clone()執行淺拷貝,因此只克隆第一個維度。

(一般來說,對於克隆是否暗示深拷貝或淺拷貝的問題,似乎沒有單一的“最佳”或“明顯”答案。開發人員想要的將取決於應用程序如何使用每個字段,因此,一刀切的方法自然會有局限性。)

由於沒有真正的多維數組,因此證明了這種行為。

Java通過生成數組來實現多個維度。 意思是:

int[][] is actually Array<Array<int>>

因此,克隆只會復制第一個維度。

如果您嘗試使用3維數組,則需要克隆三次。

clone方法是一個所謂的淺拷貝(請參閱clone方法的另一個stackoverflow答案 ),這意味着所有元素都是通過引用復制的。

要獲得你想要的東西(也稱為深度克隆)你可以自己使用Arrays.copy復制每個單獨的數組,這樣你找到的每個(子)數組都會得到一個深度克隆,或者在深層檢查這個stackoverflow答案克隆

快樂的黑客:-)

我實際上無法復制你提到的行為。 我可以看到一些答案提到淺拷貝是問題的根本原因。 糾正我,如果我錯了,淺拷貝只是意味着克隆時不是復制對象,我們將獲得參考的副本。 這里有一個很好的解釋在Java中,什么是淺層副本?

在這種情況下,淺拷貝只會確保原始數組中的更改反映在克隆數組中,但不會阻止任何內容被復制。

int[][] array = new int[][] {{1,2,3},{4,5,6}, {7,8,9}};
int[][] clone = array.clone();

//Try this to see magic of shallow copy
//array[2][1]=11;

for(int i=0;i<array.length;i++)
    for(int j=0;j<array[i].length;j++)
        System.out.println("array["+i+"]["+j+"]"+array[i][j]);

for(int i=0;i<clone.length;i++)
    for(int j=0;j<clone[i].length;j++)
        System.out.println("clone["+i+"]["+j+"]"+clone[i][j]);

對我來說,克隆完美無缺,即兩個陣列都具有相同的內容。 我能想到克服數組的問題不會顯示某些信息的唯一原因是我們在克隆之后實際修改了原始數組(然后淺拷貝進入游戲)。

順便說一句,我使用的是Java 1.6,我希望這不是問題。

編輯:如果我們只需要理解為什么它們是淺拷貝而不是多維數組的深拷貝。 讓我們看看2個事實

  1. 在克隆時,對象總是被克隆為淺拷貝(對象的引用副本),只有本機類型才能獲得真正的副本。 在Java中,什么是淺拷貝?
  2. java中的數組實際上是一個對象是一個數組,是java中的一個對象

現在結合1和2,我們知道Java中的多維數組只是一個對象,它引用了其他數組對象。

類似於ArrayObj - > {ArrayObj,ArrayObj,ArrayObj};

因為我們在對象(組合)中有對象,所以我們應該根據Java克隆規則獲得淺拷貝。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM