配列でclone()を呼び出すと、その内容も複製されますか?


92

clone()タイプAのオブジェクトの配列に対してメソッドを呼び出す場合、どのようにしてその要素を複製しますか?コピーは同じオブジェクトを参照しますか?それとも(element of type A).clone()、それらのそれぞれを必要としますか?


3
各要素でcloneを呼び出す必要があります。
Peter Lawrey、2011

回答:


77

clone()浅いコピーを作成します。つまり、要素は複製されません。(実装しなかった場合はどうなりCloneableますか?)

Arrays.copyOf(..)代わりに配列のコピーに使用したい場合がありますclone()(他のものとは異なり、配列の複製は問題ありません)。

詳細なクローンが必要な場合は、この回答を確認してください


clone()要素がCloneable次の場合でも浅さを説明する小さな例:

ArrayList[] array = new ArrayList[] {new ArrayList(), new ArrayList()};
ArrayList[] clone = array.clone();
for (int i = 0; i < clone.length; i ++) {
    System.out.println(System.identityHashCode(array[i]));
    System.out.println(System.identityHashCode(clone[i]));
    System.out.println(System.identityHashCode(array[i].clone()));
    System.out.println("-----");
}

プリント:

4384790  
4384790
9634993  
-----  
1641745  
1641745  
11077203  
-----  

2
そして、あなたがそうするつもりなら、私は個人的に使用しますSystem.arrayCopy
corsiKa

1
clone()配列で使用するのに適したオプションです。ブロッホは、彼はそれを配列にのみ使用し、他には何も使用しないと述べています。System.arrayCopy結構です。Arrays.copyOf(..)使いやすい別の方法です。
Bozho

私はそれを取り戻します-私は使用しますArrays.copyOf:-)変数を単純化するメソッドシグネチャがあり(そうすると制限されますが、ほとんどの場合に最適です)、少なくとも私のJDKでは、System.arrayCopyとにかく使用して実装されています。そのヒントをありがとう!
corsiKa 2011

@Bozho、あなたのegから。array [i]とclone [i]は同じオブジェクトを参照するため、最初の2つのsysoutは同じです。しかし、array [i] .cloneはarray [i]自体も参照するので、なぜarray [i] .clone()は異なるハッシュコード値を返すのでしょうか?
abhihello123 2013年

@weakstudent、をarray[i].clone()参照しませんarray[i]。これは、例のその部分が示していることです。
Dathan 2013年

19

タイプAのオブジェクトの配列でclone()メソッドを呼び出すと、どのようにしてその要素を複製しますか?

配列の要素は複製されません。

コピーは同じオブジェクトを参照しますか?

はい。

または、それらのそれぞれに対して(タイプAの要素).clone()を呼び出しますか?

いいえ、clone()どの要素も呼び出されません。


6

プリミティブの1D配列は、複製時に要素をコピーします。これは、2D配列(Array of Arrays)のクローンを作成するように誘惑します。

の浅いコピーの実装のため、2Dアレイのクローンは機能しないことに注意してくださいclone()

public static void main(String[] args) {
    int row1[] = {0,1,2,3};
    int row2[] =  row1.clone();
    row2[0] = 10;
    System.out.println(row1[0] == row2[0]); // prints false

    int table1[][]={{0,1,2,3},{11,12,13,14}};
    int table2[][] = table1.clone();
    table2[0][0] = 100;
    System.out.println(table1[0][0] == table2[0][0]); //prints true
}

1
cloneプリミティブの1D配列を取得して詳細なコピーを取得できると言っていませんか?すごい!うまくやっArrays.copyOfRange()System.arraycopy()
Janez Kuhar

1
はい!プリミティブの1D配列は、配列の複製時にコピーされます
Thamme Gowda

1
Thamme Gowda Nが「プリミティブ」と言っていることに注意してください。オブジェクトの配列のクローンは、参照のクローンになります。
Kristiaan 2016年

プリミティブには状態がないため、プリミティブは本質的に不変です。何の言及がないのであなたは、プリミティブの浅いコピーを作るカント
Xerus

5

クローンはアレイの浅いコピーです。

このテストコードは以下を出力します。

[1、2] / [1、2]
[100、200] / [100、2]

理由MutableIntegerとして、両方の配列に共有されているobjects[0]objects2[0]していますが、参照を変更することができますobjects[1]から独立objects2[1]

import java.util.Arrays;                                                                                                                                 

public class CloneTest {                                                                                                                                 
    static class MutableInteger {                                                                                                                        
        int value;                                                                                                                                       
        MutableInteger(int value) {                                                                                                                      
            this.value = value;                                                                                                                          
        }                                                                                                                                                
        @Override                                                                                                                                        
        public String toString() {                                                                                                                       
            return Integer.toString(value);                                                                                                              
        }                                                                                                                                                
    }                                                                                                                                                    
    public static void main(String[] args) {                                                                                                             
        MutableInteger[] objects = new MutableInteger[] {
                new MutableInteger(1), new MutableInteger(2) };                                                
        MutableInteger[] objects2 = objects.clone();                                                                                                     
        System.out.println(Arrays.toString(objects) + " / " + 
                            Arrays.toString(objects2));                                                                
        objects[0].value = 100;                                                                                                                          
        objects[1] = new MutableInteger(200);                                                                                                            
        System.out.println(Arrays.toString(objects) + " / " + 
                            Arrays.toString(objects2));                                                               
    }                                                                                                                                                    
}                                                                                                                                                        
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.