Saya akan mengatakan jawaban ini melewatkan tipuan.
Bloch, dalam Java Efektifnya yang esensial, luar biasa, dan ringkas , mengatakan, dalam item 47, judul "Ketahui dan gunakan perpustakaan", "Untuk meringkas, jangan menemukan kembali roda". Dan dia memberikan beberapa alasan yang sangat jelas mengapa tidak.
Ada beberapa jawaban di sini yang menyarankan metode-metode dari CollectionUtils
dalam pustaka Apache Commons Collections tetapi tidak ada yang menemukan cara paling indah dan elegan untuk menjawab pertanyaan ini :
Collection<Object> culprits = CollectionUtils.disjunction( list1, list2 );
if( ! culprits.isEmpty() ){
// ... do something with the culprits, i.e. elements which are not common
}
Penyebab : yaitu elemen-elemen yang tidak umum untuk keduanya Lists
. Menentukan pelaku mana yang menjadi milik list1
dan yang mana list2
relatif mudah menggunakan CollectionUtils.intersection( list1, culprits )
dan CollectionUtils.intersection( list2, culprits )
.
Namun itu cenderung berantakan dalam kasus-kasus seperti {"a", "a", "b"} disjunction
dengan {"a", "b", "b"} ... kecuali ini bukan merupakan kegagalan dari perangkat lunak, tetapi melekat pada sifat seluk-beluk / ambiguitas tugas yang diinginkan.
Anda selalu dapat memeriksa kode sumber (l. 287) untuk tugas seperti ini, seperti yang diproduksi oleh para insinyur Apache. Salah satu manfaat menggunakan kode mereka adalah bahwa kode tersebut telah dicoba dan diuji secara menyeluruh, dengan banyak kasus tepi dan kasus yang diantisipasi dan ditangani. Anda dapat menyalin dan mengubah kode ini ke isi hati Anda jika perlu.
NB Saya awalnya kecewa karena tidak ada CollectionUtils
metode yang menyediakan versi overload yang memungkinkan Anda untuk memaksakan sendiri Comparator
(sehingga Anda dapat mendefinisikan kembali equals
sesuai dengan tujuan Anda).
Tapi dari collections4 4.0 ada kelas baru, Equator
yang "menentukan kesetaraan antara objek tipe T". Pada pemeriksaan kode sumber collections4 CollectionUtils.java mereka tampaknya menggunakan ini dengan beberapa metode, tetapi sejauh yang saya bisa tahu ini tidak berlaku untuk metode di bagian atas file, menggunakan CardinalityHelper
kelas ... yang termasuk disjunction
dan intersection
.
Saya menduga bahwa orang-orang Apache belum sempat karena ini tidak sepele: Anda harus membuat sesuatu seperti kelas "AbstractEquatingCollection", yang alih-alih menggunakan elemen bawaannya equals
dan hashCode
metode harus menggunakan mereka dari Equator
untuk semua metode dasar, seperti add
, contains
, dll NB bahkan ketika Anda melihat kode sumber, AbstractCollection
tidak melaksanakan add
, juga tidak subclass abstrak seperti AbstractSet
... Anda harus menunggu sampai kelas beton seperti HashSet
dan ArrayList
sebelum add
diimplementasikan. Cukup sakit kepala.
Sementara itu perhatikan ruang ini, kurasa. Solusi sementara yang jelas adalah membungkus semua elemen Anda dalam kelas pembungkus dipesan lebih dahulu yang menggunakan equals
dan hashCode
untuk menerapkan jenis kesetaraan yang Anda inginkan ... kemudian memanipulasi Collections
objek pembungkus ini.