Mencari Perbezaan Antara Dua Daftar di Jawa

1. Gambaran keseluruhan

Mencari perbezaan antara koleksi objek dari jenis data yang sama adalah tugas pengaturcaraan yang biasa. Sebagai contoh, bayangkan kita mempunyai senarai pelajar yang melamar peperiksaan dan senarai pelajar lain yang lulus. Perbezaan antara kedua senarai tersebut akan memberi kita pelajar yang tidak lulus dalam peperiksaan.

Di Jawa , tidak ada cara eksplisit untuk mencari perbezaan antara dua daftar dalam API Senarai , walaupun ada beberapa metode pembantu yang hampir.

Dalam tutorial ringkas ini, kita akan melihat bagaimana mencari perbezaan antara kedua-dua senarai tersebut . Kami akan mencuba beberapa pendekatan yang berbeza, termasuk Java biasa (dengan dan tanpa Stream ) dan menggunakan perpustakaan pihak ketiga seperti Jambu dan Koleksi Apache Commons .

2. Persediaan Ujian

Mari mulakan dengan menentukan dua senarai, yang akan kami gunakan untuk menguji contoh kami:

public class FindDifferencesBetweenListsUnitTest { private static final List listOne = Arrays.asList("Jack", "Tom", "Sam", "John", "James", "Jack"); private static final List listTwo = Arrays.asList("Jack", "Daniel", "Sam", "Alan", "James", "George"); }

3. Menggunakan Java List API

Kita boleh membuat salinan satu senarai dan kemudian keluarkan semua biasa unsur-unsur dengan yang lain , dengan menggunakan Senarai kaedah removeAll () :

List differences = new ArrayList(listOne); differences.removeAll(listTwo); assertEquals(2, differences.size()); assertThat(differences).containsExactly("Tom", "John");

Mari balikkan ini untuk mencari perbezaan sebaliknya:

List differences = new ArrayList(listTwo); differences.removeAll(listOne); assertEquals(3, differences.size()); assertThat(differences).containsExactly("Daniel", "Alan", "George");

Kita juga harus perhatikan bahawa jika kita ingin mencari elemen yang sama antara kedua-dua senarai, List juga mengandungi kaedah retainAll .

4. Menggunakan API Aliran

Aliran Java dapat digunakan untuk melakukan operasi berurutan pada data dari koleksi, yang meliputi perbezaan penyaringan antara daftar :

List differences = listOne.stream() .filter(element -> !listTwo.contains(element)) .collect(Collectors.toList()); assertEquals(2, differences.size()); assertThat(differences).containsExactly("Tom", "John");

Seperti contoh pertama kita, kita boleh menukar susunan senarai untuk mencari elemen yang berbeza dari senarai kedua:

List differences = listTwo.stream() .filter(element -> !listOne.contains(element)) .collect(Collectors.toList()); assertEquals(3, differences.size()); assertThat(differences).containsExactly("Daniel", "Alan", "George");

Kita harus ingat bahawa panggilan List berulang kali . berisi () boleh menjadi operasi yang mahal untuk senarai yang lebih besar.

5. Menggunakan Perpustakaan Pihak Ketiga

5.1. Menggunakan Jambu Batu Google

Jambu batu mengandungi Set berguna . kaedah perbezaan , tetapi untuk menggunakannya, kita mesti menukar Senarai kita terlebih dahuluke Set :

List differences = new ArrayList(Sets.difference(Sets.newHashSet(listOne), Sets.newHashSet(listTwo))); assertEquals(2, differences.size()); assertThat(differences).containsExactlyInAnyOrder("Tom", "John");

Kita harus perhatikan bahawa menukar Daftar ke Set akan membawa kesan menduplikasi dan menyusunnya semula.

5.2. Menggunakan Koleksi Apache Commons

The CollectionUtils kelas dari Apache Commons Collections mengandungi removeAll kaedah.

Kaedah ini sama seperti Senarai . removeAll , sambil membuat koleksi baru untuk hasilnya :

List differences = new ArrayList((CollectionUtils.removeAll(listOne, listTwo))); assertEquals(2, differences.size()); assertThat(differences).containsExactly("Tom", "John");

6. Mengendalikan Nilai Pendua

Sekarang mari kita mencari perbezaan apabila dua senarai mengandungi nilai pendua.

Untuk mencapainya, kita perlu mengeluarkan unsur pendua dari senarai pertama, tepat seberapa banyak yang terkandung dalam senarai kedua.

Dalam contoh kami, nilai "Jack" muncul dua kali dalam senarai pertama dan hanya sekali dalam senarai kedua:

List differences = new ArrayList(listOne); listTwo.forEach(differences::remove); assertThat(differences).containsExactly("Tom", "John", "Jack");

Kami juga dapat mencapainya dengan menggunakan kaedah tolak dari Apache Commons Collections :

List differences = new ArrayList(CollectionUtils.subtract(listOne, listTwo)); assertEquals(3, differences.size()); assertThat(differences).containsExactly("Tom", "John", "Jack");

7. Kesimpulannya

Dalam artikel ini, kami meneroka beberapa cara untuk mencari perbezaan antara senarai .

Dalam contohnya, kami membahas penyelesaian asas Java , penyelesaian menggunakan Streams API, dan dengan perpustakaan pihak ketiga seperti Koleksi Google Jambu dan Apache Commons.

Kami juga melihat bagaimana menangani nilai pendua.

Seperti biasa, kod sumber lengkap boleh didapati di GitHub.