Pronalaženje razlika između dva popisa u Javi

1. Pregled

Pronalaženje razlika između zbirki objekata iste vrste podataka čest je programski zadatak. Kao primjer, zamislimo da imamo popis učenika koji su se prijavili za ispit i još jedan popis studenata koji su ga položili. Razlika između ta dva popisa dala bi nam studente koji nisu položili ispit.

U Java, nema eksplicitnog načina za pronalaženje razlika između dva popisa u Popis API, iako postoje neke pomoćne metode koje se približavaju.

U ovom brzom vodiču, pogledat ćemo kako pronaći razlike između dva popisa. Isprobat ćemo nekoliko različitih pristupa, uključujući obični Java (sa i bez Potoci) i korištenjem neovisnih knjižnica poput Guava i Zbirke Apache Commons.

2. Postavljanje testa

Počnimo s definiranjem dva popisa koja ćemo koristiti za testiranje naših primjera:

javna klasa FindDifferencesBetweenListsUnitTest {private static final List listOne = Arrays.asList ("Jack", "Tom", "Sam", "John", "James", "Jack"); privatni statički konačni popis listTwo = Arrays.asList ("Jack", "Daniel", "Sam", "Alan", "James", "George"); }

3. Korištenje Jave Popis API

Možemo stvoriti kopija jednog popisa, a zatim uklonite sve elemente zajedničke drugom, koristiti Popis metoda ukloniti sve():

Razlike na popisu = novi ArrayList (listOne); razlike.removeAll (listTwo); assertEquals (2, razlike.size ()); assertThat (razlike) .containsExactly ("Tom", "John");

Preokrenimo ovo kako bismo pronašli razlike obrnuto:

Razlike u popisu = novi ArrayList (listTwo); razlike.removeAll (listOne); assertEquals (3, razlike.size ()); assertThat (razlike) .containEhactly ("Daniel", "Alan", "George");

Također bismo trebali primijetiti da ako želimo pronaći zajedničke elemente između dva popisa, Popis također sadrži a zadržiSve metoda.

4. Korištenje Streams API-ja

Java Stream može se koristiti za izvođenje sekvencijalnih operacija podataka iz zbirki, što uključuje filtriranje razlika između popisa:

Razlike u popisu = listOne.stream () .filter (element ->! ListTwo.contens (element)) .collect (Collectors.toList ()); assertEquals (2, razlike.size ()); assertThat (razlike) .containsExactly ("Tom", "John");

Kao u našem prvom primjeru, možemo promijeniti redoslijed popisa kako bismo pronašli različite elemente s drugog popisa:

Razlike u popisu = listTwo.stream () .filter (element ->! ListOne.contens (element)) .collect (Collectors.toList ()); assertEquals (3, razlike.size ()); assertThat (razlike) .containEhactly ("Daniel", "Alan", "George");

Trebali bismo napomenuti da je ponovljeni poziv od Popis.sadrži () može biti skupa operacija za veće popise.

5. Korištenje Neovisne knjižnice

5.1. Korištenje Google Guave

Guava sadrži zgodan Kompleti.razlika metoda, ali da bismo ga koristili, prvo moramo pretvoriti naš Popis do a Postavi:

Razlike u popisu = novi ArrayList (Sets.difference (Sets.newHashSet (listOne), Sets.newHashSet (listTwo))); assertEquals (2, razlike.size ()); assertThat (razlike) .containsExactlyInAnyOrder ("Tom", "John");

Trebali bismo napomenuti da pretvaranje Popis do a Postavi imat će učinak dedupliciranja i preuređivanja.

5.2. Korištenje zbirki Apache Commons

The CollectionUtils razred iz Zbirke Apache Commons sadrži a ukloniti sve metoda.

Ova metoda čini isto kao Popis.ukloniti sve, istovremeno stvarajući i novu kolekciju rezultata:

Razlike u popisu = novi ArrayList ((CollectionUtils.removeAll (listOne, listTwo))); assertEquals (2, razlike.size ()); assertThat (razlike) .containsExactly ("Tom", "John");

6. Rukovanje dvostrukim vrijednostima

Pogledajmo sada pronalaženje razlika kada dva popisa sadrže duplicirane vrijednosti.

Da biste to postigli, moramo ukloniti dvostruke elemente s prvog popisa, upravo onoliko puta koliko su sadržani na drugom popisu.

U našem primjeru vrijednost "Utičnica" pojavljuje se dva puta na prvom popisu i samo jednom na drugom popisu:

Razlike na popisu = novi ArrayList (listOne); listTwo.forEach (razlike :: ukloni); assertThat (razlike) .containsExactly ("Tom", "John", "Jack");

To također možemo postići pomoću oduzeti metoda iz Zbirke Apache Commons:

Razlike u popisu = novi ArrayList (CollectionUtils.subtract (listOne, listTwo)); assertEquals (3, razlike.size ()); assertThat (razlike) .containsExactly ("Tom", "John", "Jack");

7. Zaključak

U ovom članku, istražili smo nekoliko načina kako pronaći razlike između popisa.

U primjerima smo obradili osnovno Java rješenje, rješenje pomoću Potoci API i s bibliotekama trećih strana poput Google Guava i Zbirke Apache Commons.

Također smo vidjeli kako postupati s dvostrukim vrijednostima.

Kao i uvijek, cjeloviti izvorni kod dostupan je na GitHub-u.