Saya suka pertanyaan ini! Terutama karena hampir tidak pernah dijawab atau dijawab dengan buruk. Sepertinya belum ada yang tahu. Wilayah perawan :)
Pertama, jangan pernah berpikir untuk menggunakan equals
. Kontrak equals
, sebagaimana didefinisikan dalam javadoc, adalah relasi ekivalen (refleksif, simetris, dan transitif), bukan relasi kesetaraan. Untuk itu, juga harus antisimetris. Satu-satunya implementasi dari equals
itu adalah (atau bisa jadi) hubungan kesetaraan yang sebenarnya adalah yang ada di java.lang.Object
. Bahkan jika Anda menggunakannya equals
untuk membandingkan semua yang ada di grafik, risiko melanggar kontrak cukup tinggi. Seperti yang ditunjukkan Josh Bloch dalam Effective Java , kontrak yang setara sangat mudah diputuskan:
"Tidak ada cara untuk memperluas kelas yang bisa dipakai dan menambahkan aspek sambil mempertahankan kontrak yang sama"
Selain itu, apa gunanya metode boolean bagi Anda? Akan menyenangkan untuk benar-benar merangkum semua perbedaan antara yang asli dan klon, bukan begitu? Selain itu, saya akan berasumsi di sini bahwa Anda tidak ingin direpotkan dengan menulis / memelihara kode perbandingan untuk setiap objek dalam grafik, tetapi Anda sedang mencari sesuatu yang akan diskalakan dengan sumber karena berubah seiring waktu.
Jadi, yang benar-benar Anda inginkan adalah semacam alat perbandingan keadaan. Bagaimana alat itu diterapkan sangat bergantung pada sifat model domain Anda dan batasan kinerja Anda. Menurut pengalaman saya, tidak ada peluru ajaib yang umum. Dan itu akan menjadi lambat pada sejumlah besar iterasi. Tetapi untuk menguji kelengkapan operasi klon, itu akan melakukan pekerjaan dengan cukup baik. Dua pilihan terbaik Anda adalah serialisasi dan refleksi.
Beberapa masalah yang akan Anda temui:
- Urutan koleksi: Haruskah dua koleksi dianggap serupa jika memiliki objek yang sama, tetapi dalam urutan yang berbeda?
- Kolom mana yang harus diabaikan: Transient? Statis?
- Jenis kesetaraan: Haruskah nilai bidang memiliki jenis yang persis sama? Atau apakah boleh bagi yang satu untuk memperpanjang yang lain?
- Masih ada lagi, tapi aku lupa ...
XStream cukup cepat dan dikombinasikan dengan XMLUnit akan melakukan pekerjaan hanya dalam beberapa baris kode. XMLUnit bagus karena dapat melaporkan semua perbedaan, atau berhenti pada yang pertama ditemukan. Dan hasilnya mencakup xpath ke node yang berbeda, yang bagus. Secara default tidak mengizinkan koleksi yang tidak berurutan, tetapi dapat dikonfigurasi untuk melakukannya. Dengan memasukkan penangan perbedaan khusus (Disebut a DifferenceListener
), Anda dapat menentukan cara yang Anda inginkan untuk menangani perbedaan, termasuk mengabaikan urutan. Namun, segera setelah Anda ingin melakukan apa pun selain penyesuaian yang paling sederhana, penulisannya menjadi sulit dan detailnya cenderung terikat pada objek domain tertentu.
Preferensi pribadi saya adalah menggunakan refleksi untuk menggilir semua bidang yang dinyatakan dan menelusuri ke masing-masing, melacak perbedaan saat saya pergi. Kata peringatan: Jangan gunakan rekursi kecuali Anda menyukai pengecualian stack overflow. Jaga hal-hal dalam ruang lingkup dengan tumpukan (gunakan fileLinkedList
atau sesuatu). Saya biasanya mengabaikan bidang sementara dan statis, dan saya melewatkan pasangan objek yang telah saya bandingkan, jadi saya tidak berakhir di loop tanpa batas jika seseorang memutuskan untuk menulis kode referensi sendiri (Namun, saya selalu membandingkan pembungkus primitif apa pun yang terjadi. , karena referensi objek yang sama sering digunakan kembali). Anda dapat mengonfigurasi hal-hal di depan untuk mengabaikan pengurutan koleksi dan untuk mengabaikan jenis atau bidang khusus, tetapi saya ingin menentukan kebijakan perbandingan status saya pada bidang itu sendiri melalui penjelasan. Ini, IMHO, adalah persis apa penjelasan yang dimaksudkan untuk, untuk membuat data meta tentang kelas tersedia pada waktu proses. Sesuatu seperti:
@StatePolicy(unordered=true, ignore=false, exactTypesOnly=true)
private List<StringyThing> _mylist;
Saya pikir ini sebenarnya masalah yang sangat sulit, tetapi benar-benar bisa dipecahkan! Dan begitu Anda memiliki sesuatu yang sesuai untuk Anda, itu sangat, sangat, berguna :)
Jadi semoga berhasil. Dan jika Anda menemukan sesuatu yang benar-benar jenius, jangan lupa untuk membagikannya!