Apakah memanggil clone () pada array juga mengkloning isinya?
92
Jika saya memanggil clone()metode pada array Objek tipe A, bagaimana cara mengkloning elemennya? Akankah salinan tersebut merujuk ke objek yang sama? Atau akankah itu memanggil (element of type A).clone()mereka masing-masing?
clone()membuat salinan dangkal. Artinya, elemen tersebut tidak akan dikloning. (Bagaimana jika mereka tidak menerapkan Cloneable?)
Anda mungkin ingin menggunakan Arrays.copyOf(..)untuk menyalin larik daripada clone()(meskipun kloning baik-baik saja untuk larik, tidak seperti untuk hal lain)
Sebuah contoh kecil untuk menggambarkan kedangkalan clone()bahkan jika elemennya adalah 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("-----");
}
Dan, jika Anda akan melakukan itu, secara pribadi saya akan menggunakanSystem.arrayCopy
corsiKa
1
clone()adalah pilihan yang bagus untuk digunakan dengan array..hampir eksklusif. Bloch menyebutkan bahwa dia akan menggunakannya hanya untuk array dan tidak ada yang lain. System.arrayCopybaik-baik saja. Arrays.copyOf(..)adalah alternatif lain yang lebih mudah digunakan.
Bozho
Saya mengambilnya kembali - saya akan menggunakan Arrays.copyOf:-) Ini memiliki tanda tangan metode yang menyederhanakan variabel (ya itu membatasi Anda, tetapi itu sempurna untuk kebanyakan kasus) dan setidaknya di JDK saya, itu diterapkan dengan System.arrayCopytetap. Terima kasih atas tip itu!
corsiKa
@ Bozho, dari contoh Anda. array [i] dan clone [i] akan merujuk ke objek yang sama sehingga dua sysout pertama sama. Tetapi array [i] .clone juga akan merujuk ke array [i] itu sendiri jadi mengapa array [i] .clone () mengembalikan nilai kode hash yang berbeda?
abhihello123
@weakstudent, array[i].clone()TIDAK mengacu pada array[i]. Itulah yang ditunjukkan oleh bagian dari contoh itu.
Dathan
19
Jika saya memanggil metode clone () pada array Objek tipe A, bagaimana cara mengkloning elemennya?
Elemen array tidak akan digandakan.
Akankah salinan tersebut merujuk ke objek yang sama?
Iya.
Atau akan memanggil (elemen tipe A) .clone () untuk masing-masing?
Tidak, itu tidak akan memanggil clone()salah satu elemen.
Apakah Anda memberi tahu saya bahwa saya bisa clone1D berbagai primitif dan mendapatkan salinan yang dalam? Itu luar biasa! Tarif baik Arrays.copyOfRange(), System.arraycopy()!
Janez Kuhar
1
Yessssss! Array 1D primitif disalin ketika array dikloning
Thamme Gowda
1
Perhatikan bahwa Thamme Gowda N mengatakan "primitif". Klon array objek hanya akan menjadi tiruan referensi.
Kristiaan
karena primitif tidak memiliki status, mereka secara inheren tidak dapat diubah. Anda tidak dapat membuat salinan primitif yang dangkal, karena tidak ada referensi
Xerus
5
Klon adalah salinan larik yang dangkal.
Kode tes ini mencetak:
[1, 2] / [1, 2]
[100, 200] / [100, 2]
karena MutableIntegerini dibagi dalam kedua larik sebagai objects[0]dan objects2[0], tetapi Anda dapat mengubah referensi objects[1]secara independen dari objects2[1].
Jawaban:
clone()
membuat salinan dangkal. Artinya, elemen tersebut tidak akan dikloning. (Bagaimana jika mereka tidak menerapkanCloneable
?)Anda mungkin ingin menggunakan
Arrays.copyOf(..)
untuk menyalin larik daripadaclone()
(meskipun kloning baik-baik saja untuk larik, tidak seperti untuk hal lain)Jika Anda ingin kloning yang dalam, periksa jawaban ini
Sebuah contoh kecil untuk menggambarkan kedangkalan
clone()
bahkan jika elemennya adalahCloneable
: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("-----"); }
Cetakan:
4384790 4384790 9634993 ----- 1641745 1641745 11077203 -----
sumber
System.arrayCopy
clone()
adalah pilihan yang bagus untuk digunakan dengan array..hampir eksklusif. Bloch menyebutkan bahwa dia akan menggunakannya hanya untuk array dan tidak ada yang lain.System.arrayCopy
baik-baik saja.Arrays.copyOf(..)
adalah alternatif lain yang lebih mudah digunakan.Arrays.copyOf
:-) Ini memiliki tanda tangan metode yang menyederhanakan variabel (ya itu membatasi Anda, tetapi itu sempurna untuk kebanyakan kasus) dan setidaknya di JDK saya, itu diterapkan denganSystem.arrayCopy
tetap. Terima kasih atas tip itu!array[i].clone()
TIDAK mengacu padaarray[i]
. Itulah yang ditunjukkan oleh bagian dari contoh itu.Elemen array tidak akan digandakan.
Iya.
Tidak, itu tidak akan memanggil
clone()
salah satu elemen.sumber
Array 1D primitif tidak menyalin elemen saat dikloning. Ini menggoda kita untuk mengkloning array 2D (Array of Arrays).
Ingat bahwa klon array 2D tidak berfungsi karena implementasi salinan dangkal
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 }
sumber
clone
1D berbagai primitif dan mendapatkan salinan yang dalam? Itu luar biasa! Tarif baikArrays.copyOfRange()
,System.arraycopy()
!Klon adalah salinan larik yang dangkal.
Kode tes ini mencetak:
karena
MutableInteger
ini dibagi dalam kedua larik sebagaiobjects[0]
danobjects2[0]
, tetapi Anda dapat mengubah referensiobjects[1]
secara independen dariobjects2[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)); } }
sumber