Megtalálni a különbségeket a Java két listája között

1. Áttekintés

Az azonos adattípusú objektumok gyűjteményei közötti különbségek megtalálása gyakori programozási feladat. Példaként képzeljük el, hogy van egy listánk azokról a hallgatókról, akik jelentkeztek egy vizsgára, és egy másik, azon hallgatók listája, akik vizsgára jelentkeztek. A két lista közötti különbség azt a tanulót jelentené nekünk, aki nem teljesítette a vizsgát.

Ban ben Jáva, nincs kifejezett módja a két lista közötti különbségek megtalálására a Lista API, bár vannak olyan segítő módszerek, amelyek közel állnak.

Ebben a gyors bemutatóban megnézzük, hogyan lehet megtalálni a különbségeket a két lista között. Megpróbálunk néhány különböző megközelítést, beleértve az egyszerűt is Jáva (és anélkül Patakok) és harmadik féltől származó könyvtárak, például Gujávafa és a Apache Commons Gyűjtemények.

2. Tesztelje a telepítést

Kezdjük két lista meghatározásával, amelyeket a példáink kipróbálására használunk:

public class FindDifferencesBetweenListsUnitTest {private static final List listOne = Arrays.asList ("Jack", "Tom", "Sam", "John", "James", "Jack"); statikus privát statisztikai lista ListTwo = Arrays.asList ("Jack", "Daniel", "Sam", "Alan", "James", "George"); }

3. A Java használata Lista API

Hozhatunk létre a az egyik lista másolatát, majd távolítsa el a másikkal közös elemeket, használni a Lista módszer összes eltávolítása():

Lista különbségek = new ArrayList (listOne); különbségek.removeAll (listTwo); assertEquals (2, különbségek.méret ()); assertThat (különbségek) .conactExactly ("Tom", "John");

Fordítsuk meg ezt, hogy fordítva találjuk meg a különbségeket:

Lista különbségek = new ArrayList (listTwo); különbségek.removeAll (listOne); assertEquals (3, különbségek.méret ()); assertThat (különbségek). pontosan tartalmaz ("Daniel", "Alan", "George");

Azt is meg kell jegyeznünk, hogy ha meg akarjuk találni a közös elemeket a két lista között, Lista tartalmaz egy retainAll módszer.

4. A Streams API használata

Egy Java Folyam használható szekvenciális műveletek végrehajtására a gyűjtemények adatairól, ideértve a következőket: a listák közötti különbségek szűrése:

Lista különbségek = listOne.stream () .filter (element ->! ListTwo.contains (element)) .collect (Collectors.toList ()); assertEquals (2, különbségek.méret ()); assertThat (különbségek) .conactExactly ("Tom", "John");

Az első példánkhoz hasonlóan a listák sorrendjét is megváltoztathatjuk, hogy megtaláljuk a különböző elemeket a második listából:

Lista különbségek = listTwo.stream () .filter (element ->! ListOne.contains (element)) .collect (Collectors.toList ()); assertEquals (3, különbségek.méret ()); assertThat (különbségek). pontosan tartalmaz ("Daniel", "Alan", "George");

Meg kell jegyeznünk, hogy a Lista.tartalmaz () nagyobb listák esetén költséges művelet lehet.

5. Használata Harmadik fél könyvtárai

5.1. A Google Guava használata

Gujávafa tartalmaz egy praktikus Készletek.különbség módszer, de a használatához először át kell alakítanunk a Lista a Készlet:

Lista különbségek = new ArrayList (Sets.difference (Sets.newHashSet (listOne), Sets.newHashSet (listTwo))); assertEquals (2, különbségek.méret ()); assertThat (különbségek) .conactExactlyInAnyOrder ("Tom", "John");

Meg kell jegyeznünk, hogy a Lista a Készlet lesz a hatásának deduplikálása és átrendezése.

5.2. Az Apache Commons gyűjtemények használata

A CollectionUtils osztály tól Apache Commons Gyűjtemények tartalmaz egy összes eltávolítása módszer.

Ez a módszer a ugyanaz, mint a Lista.összes eltávolítása, miközben egy új kollekciót is létrehozott az eredményhez:

Lista különbségek = new ArrayList ((CollectionUtils.removeAll (listOne, listTwo))); assertEquals (2, különbségek.méret ()); assertThat (különbségek) .conactExactly ("Tom", "John");

6. Ismétlődő értékek kezelése

Most nézzük meg a különbségek megtalálását, amikor két lista duplikált értékeket tartalmaz.

Elérni ezt, el kell távolítanunk az ismétlődő elemeket az első listáról, pontosan annyiszor, ahányszor a második listában szerepelnek.

Példánkban az érték "Jack" kétszer jelenik meg az első listában, és csak egyszer a második listában:

Lista különbségek = new ArrayList (listOne); listTwo.forEach (különbségek :: eltávolítás); assertThat (különbségek). pontosan tartalmaz ("Tom", "John", "Jack");

Ezt is elérhetjük a kivonni módszer től Apache Commons Gyűjtemények:

Lista különbségek = new ArrayList (CollectionUtils.subtract (listOne, listTwo)); assertEquals (3, különbségek.méret ()); assertThat (különbségek). pontosan tartalmaz ("Tom", "John", "Jack");

7. Következtetés

Ebben a cikkben, feltártunk néhány módszert a listák közötti különbségek megtalálására.

A példákban egy alapvető Java megoldással foglalkoztunk, megoldás a Patakok API, és harmadik féltől származó könyvtárakkal Google Guava és Apache Commons Gyűjtemények.

Azt is láttuk, hogyan kell kezelni az ismétlődő értékeket.

Mint mindig, a teljes forráskód elérhető a GitHubon.