Finne forskjellene mellom to lister i Java

1. Oversikt

Å finne forskjeller mellom samlinger av objekter av samme datatype er en vanlig programmeringsoppgave. Tenk deg at vi har en liste over studenter som har søkt eksamen og en annen liste over studenter som har bestått. Forskjellen mellom disse to listene ville gi oss studentene som ikke besto eksamen.

I Java, det er ingen eksplisitt måte å finne forskjeller mellom to lister i Liste API, selv om det er noen hjelpemetoder som kommer i nærheten.

I denne raske opplæringen, vi ser på hvordan vi finner forskjellene mellom de to listene. Vi prøver noen forskjellige tilnærminger, inkludert vanlig Java (med og uten Strømmer) og bruker tredjepartsbiblioteker som Guava og Apache Commons samlinger.

2. Testoppsett

La oss begynne med å definere to lister, som vi vil bruke til å teste ut eksemplene våre:

offentlig klasse FindDifferencesBetweenListsUnitTest {private static final List listOne = Arrays.asList ("Jack", "Tom", "Sam", "John", "James", "Jack"); privat statisk endelig List listTwo = Arrays.asList ("Jack", "Daniel", "Sam", "Alan", "James", "George"); }

3. Bruke Java Liste API

Vi kan lage en kopi av den ene listen, og fjern deretter alle elementene som er felles med den andre, bruker Liste metode Fjern alle():

Listeforskjeller = ny ArrayList (listOne); difference.removeAll (listTwo); assertEquals (2, difference.size ()); assertThat (forskjeller). inneholder nøyaktig ("Tom", "John");

La oss snu dette for å finne forskjellene omvendt:

Listeforskjeller = ny ArrayList (listTwo); difference.removeAll (listOne); assertEquals (3, difference.size ()); hevder at (forskjeller). inneholder nøyaktig ("Daniel", "Alan", "George");

Vi bør også merke oss at hvis vi vil finne de felles elementene mellom de to listene, Liste inneholder også en beholder alt metode.

4. Bruke Streams API

En Java Strøm kan brukes til å utføre sekvensielle operasjoner på data fra samlinger, som inkluderer filtrering av forskjeller mellom lister:

Listeforskjeller = listOne.stream () .filter (element ->! ListTwo.contains (element)) .collect (Collectors.toList ()); assertEquals (2, difference.size ()); assertThat (forskjeller). inneholder nøyaktig ("Tom", "John");

Som i vårt første eksempel kan vi bytte rekkefølgen på lister for å finne de forskjellige elementene fra den andre listen:

Listeforskjeller = listTwo.stream () .filter (element ->! ListOne.contains (element)) .collect (Collectors.toList ()); assertEquals (3, difference.size ()); hevder at (forskjeller). inneholder nøyaktig ("Daniel", "Alan", "George");

Vi bør merke oss at gjentatte kall av Liste.inneholder () kan være en kostbar operasjon for større lister.

5. Bruke Tredjepartsbiblioteker

5.1. Bruke Google Guava

Guava inneholder en hendig Settene.forskjell metode, men for å bruke den må vi først konvertere vår Liste til en Sett:

Listeforskjeller = ny ArrayList (Sets. Forskjell (Sets.newHashSet (listOne), Sets.newHashSet (listTwo))); assertEquals (2, difference.size ()); assertThat (forskjeller) .containsExactlyInAnyOrder ("Tom", "John");

Vi bør merke oss at konvertering av Liste til en Sett vil ha effekten av å duplisere og omorganisere den.

5.2. Bruke Apache Commons-samlinger

De CollectionUtils klasse fra Apache Commons samlinger inneholder en Fjern alle metode.

Denne metoden gjør samme som Liste.Fjern alle, samtidig som du også oppretter en ny samling for resultatet:

Listeforskjeller = ny ArrayList ((CollectionUtils.removeAll (listOne, listTwo))); assertEquals (2, difference.size ()); assertThat (forskjeller). inneholder nøyaktig ("Tom", "John");

6. Håndtering av dupliserte verdier

La oss nå se på å finne forskjeller når to lister inneholder dupliserte verdier.

For å oppnå dette, vi må fjerne duplikatelementene fra den første listen, nøyaktig så mange ganger som de finnes i den andre listen.

I vårt eksempel, verdien “Jack” vises to ganger i den første listen og bare en gang i den andre listen:

Listeforskjeller = ny ArrayList (listOne); listTwo.forEach (forskjeller :: fjern); hevder at (forskjeller). inneholder nøyaktig ("Tom", "John", "Jack");

Vi kan også oppnå dette ved hjelp av trekke fra metode fra Apache Commons samlinger:

Listeforskjeller = ny ArrayList (CollectionUtils.subtract (listOne, listTwo)); assertEquals (3, difference.size ()); hevder at (forskjeller). inneholder nøyaktig ("Tom", "John", "Jack");

7. Konklusjon

I denne artikkelen, vi utforsket noen måter å finne forskjeller mellom lister.

I eksemplene dekket vi en grunnleggende Java-løsning, en løsning ved hjelp av Strømmer API, og med tredjepartsbiblioteker som Google Guava og Apache Commons samlinger.

Vi så også hvordan vi skulle håndtere dupliserte verdier.

Som alltid er den komplette kildekoden tilgjengelig på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found