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.