Bagaimana saya bisa mengkloning ArrayList
dan juga mengkloning item-itemnya di Java?
Misalnya saya punya:
ArrayList<Dog> dogs = getDogs();
ArrayList<Dog> clonedList = ....something to do with dogs....
Dan saya berharap bahwa objek di clonedList
tidak sama dengan daftar anjing.
java
collections
clone
deep-copy
palig
sumber
sumber
Jawaban:
Anda perlu mengulang item, dan mengkloningnya satu per satu, menempatkan klon dalam array hasil Anda.
Agar itu berfungsi, tentu saja, Anda harus membuat
Dog
kelas Anda mengimplementasikanCloneable
antarmuka dan mengganticlone()
metode.sumber
Saya, secara pribadi, akan menambahkan konstruktor ke Dog:
Kemudian hanya iterate (seperti yang ditunjukkan dalam jawaban Varkhan):
Saya menemukan keuntungan dari ini adalah Anda tidak perlu main-main dengan barang-barang Cloneable yang rusak di Jawa. Ini juga cocok dengan cara Anda menyalin koleksi Java.
Pilihan lain bisa dengan menulis antarmuka ICloneable Anda sendiri dan menggunakannya. Dengan begitu Anda bisa menulis metode generik untuk kloning.
sumber
cloneList(List<Object>)
atauDog(Object)
?Semua koleksi standar memiliki salinan konstruktor. Gunakan itu.
clone()
dirancang dengan beberapa kesalahan (lihat pertanyaan ini ), jadi yang terbaik adalah menghindarinya.Dari Effective Java 2nd Edition , Item 11: Override clone dengan bijaksana
Buku ini juga menjelaskan banyak keunggulan yang dimiliki copy constructor daripada Cloneable / clone.
Pertimbangkan manfaat lain menggunakan copy constructor: Misalkan Anda memiliki
HashSet s
, dan Anda ingin menyalinnya sebagaiTreeSet
. Metode klon tidak dapat menawarkan fungsi ini, tapi mudah dengan konstruktor konversi:new TreeSet(s)
.sumber
Java 8 menyediakan cara baru untuk memanggil metode copy constructor atau clone pada elemen dogs secara elegan dan kompak: Streaming , lambdas dan kolektor .
Salin konstruktor:
Ungkapan
Dog::new
ini disebut referensi metode . Ini menciptakan objek fungsi yang memanggil konstruktorDog
yang mengambil anjing lain sebagai argumen.Metode klon [1]:
Mendapatkan
ArrayList
sebagai hasilnyaAtau, jika Anda harus mendapatkan
ArrayList
kembali (jika Anda ingin mengubahnya nanti):Perbarui daftar di tempat
Jika Anda tidak perlu menyimpan konten asli dari
dogs
daftar Anda bisa menggunakanreplaceAll
metode ini dan memperbarui daftar di tempat:Semua contoh mengasumsikan
import static java.util.stream.Collectors.*;
.Kolektor untuk
ArrayList
sKolektor dari contoh terakhir dapat dibuat menjadi metode util. Karena ini adalah hal yang biasa dilakukan, saya pribadi suka itu pendek dan cantik. Seperti ini:
[1] Catatan tentang
CloneNotSupportedException
:Agar solusi ini berfungsi,
clone
metodeDog
harus tidak menyatakan bahwa ia melemparCloneNotSupportedException
. Alasannya adalah bahwa argumen untukmap
tidak diizinkan untuk membuang pengecualian yang diperiksa.Seperti ini:
Namun ini seharusnya tidak menjadi masalah besar, karena itu adalah praktik terbaik. ( Effectice Java misalnya memberikan saran ini.)
Terima kasih kepada Gustavo karena memperhatikan ini.
PS:
Jika Anda merasa lebih cantik, Anda dapat menggunakan sintaks referensi metode untuk melakukan hal yang persis sama:
sumber
List<Dog> clonedDogs = new ArrayList<>(); dogs.stream().parallel().forEach(d -> clonedDogs.add(new Dog(d)));
parallel
panggilan membuatclonedDogs.add
dipanggil dari beberapa utas pada saat yang sama. Versi yang menggunakancollect
aman-utas. Ini adalah salah satu keunggulan model fungsional perpustakaan aliran, kode yang sama dapat digunakan untuk aliran paralel.Unhandled exception type CloneNotSupportedException
ond.clone()
. Mendeklarasikan pengecualian atau menangkapnya tidak menyelesaikannya.Dog
dalam contoh ini) tidak mendukung kloning. Apakah Anda yakin itu mengimplementasikanClonable
antarmuka?Pada dasarnya ada tiga cara tanpa iterasi secara manual,
1 Menggunakan konstruktor
2 Menggunakan
addAll(Collection<? extends E> c)
3 Menggunakan
addAll(int index, Collection<? extends E> c)
metode denganint
parameterNB: Perilaku operasi ini akan tidak ditentukan jika koleksi yang ditentukan dimodifikasi saat operasi sedang berlangsung.
sumber
Saya pikir jawaban hijau saat ini buruk , mengapa Anda bertanya?
Cara serialisasi juga imo buruk, Anda mungkin harus menambahkan Serializable di semua tempat.
Jadi apa solusinya:
Pustaka Java-Kloning Mendalam Pustaka kloning adalah pustaka java kecil, open source (lisensi apache) yang mendefonikan objek. Objek tidak harus mengimplementasikan antarmuka Cloneable. Secara efektif, perpustakaan ini dapat mengkloning objek java APAPUN. Itu dapat digunakan yaitu dalam implementasi cache jika Anda tidak ingin objek yang di-cache dimodifikasi atau kapan pun Anda ingin membuat salinan objek yang dalam.
Lihat di https://github.com/kostaskougios/cloning
sumber
Saya telah menemukan cara, Anda dapat menggunakan json untuk membuat serial / unserialize daftar. Daftar serial tidak memiliki referensi ke objek asli saat tidak di-serialisasi.
Menggunakan gson:
Anda dapat melakukannya dengan menggunakan jackson dan perpustakaan json lainnya juga.
sumber
Saya selalu menggunakan opsi ini:
sumber
Anda perlu mengkloning
ArrayList
dengan tangan (dengan mengulanginya dan menyalin setiap elemen ke yang baruArrayList
), karenaclone()
tidak akan melakukannya untuk Anda. Alasan untuk ini adalah bahwa benda-benda yang terkandung dalamArrayList
mungkin tidak mengimplementasikanClonable
diriSunting : ... dan itulah yang dilakukan oleh kode Varkhan.
sumber
Cara jahat adalah melakukannya dengan refleksi. Sesuatu seperti ini bekerja untuk saya.
sumber
original
berisi objek dari kelas yang berbeda saya pikircloneMethod.invoke
akan gagal dengan pengecualian ketika dipanggil dengan objek yang salah. Karena ini mungkin lebih baik untuk mengambil klon spesifikMethod
untuk setiap objek. Atau gunakan metode klon padaObject
(tetapi karena itu dilindungi yang mungkin gagal dalam lebih banyak kasus).Ini akan menyalin setiap anjing
sumber
Poster-poster lain benar: Anda perlu mengulang daftar dan menyalin ke daftar baru.
Namun ... Jika objek dalam daftar tidak dapat diubah - Anda tidak perlu mengkloningnya. Jika objek Anda memiliki grafik objek yang kompleks - mereka juga harus tidak berubah.
Manfaat lain dari kekekalan adalah mereka juga threadsafe.
sumber
Berikut ini solusi menggunakan tipe templat generik:
sumber
untuk Anda objek menimpa metode clone ()
dan panggilan .clone () untuk Vector obj atau ArraiList obj ....
sumber
Cara mudah dengan menggunakan commons-lang-2.3.jar perpustakaan java ke daftar clone
tautan unduh commons-lang-2.3.jar
Cara Penggunaan
Saya harap yang ini bisa membantu.
: D
sumber
Paket
import org.apache.commons.lang.SerializationUtils;
Ada sebuah metode
SerializationUtils.clone(Object);
Contoh
sumber
Saya baru saja mengembangkan lib yang mampu mengkloning objek entitas dan objek java.util.List. Cukup unduh toples di https://drive.google.com/open?id=0B69Sui5ah93EUTloSktFUkctN0U dan gunakan metode statis cloneListObject (Daftar daftar). Metode ini tidak hanya mengkloning Daftar tetapi juga semua elemen entitas.
sumber
Di bawah ini bekerja untuk saya ..
di Dog.java
Di sini daftar baru yang dibuat dari metode createCopy dibuat melalui SerializationUtils.clone (). Jadi setiap perubahan yang dilakukan ke daftar baru tidak akan memengaruhi daftar asli
sumber
Saya pikir saya menemukan cara yang sangat mudah untuk membuat salinan ArrayList yang mendalam. Dengan asumsi Anda ingin menyalin array ArrayList StringA.
Beri tahu saya jika itu tidak berhasil untuk Anda.
sumber