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 CollectionUtilsdalam 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 list1dan yang mana list2relatif mudah menggunakan CollectionUtils.intersection( list1, culprits )dan CollectionUtils.intersection( list2, culprits ).
Namun itu cenderung berantakan dalam kasus-kasus seperti {"a", "a", "b"} disjunctiondengan {"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 CollectionUtilsmetode yang menyediakan versi overload yang memungkinkan Anda untuk memaksakan sendiri Comparator(sehingga Anda dapat mendefinisikan kembali equalssesuai dengan tujuan Anda).
Tapi dari collections4 4.0 ada kelas baru, Equatoryang "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 CardinalityHelperkelas ... yang termasuk disjunctiondan 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 equalsdan hashCodemetode harus menggunakan mereka dari Equatoruntuk semua metode dasar, seperti add, contains, dll NB bahkan ketika Anda melihat kode sumber, AbstractCollectiontidak melaksanakan add, juga tidak subclass abstrak seperti AbstractSet... Anda harus menunggu sampai kelas beton seperti HashSetdan ArrayListsebelum adddiimplementasikan. 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 equalsdan hashCodeuntuk menerapkan jenis kesetaraan yang Anda inginkan ... kemudian memanipulasi Collectionsobjek pembungkus ini.