Apache Commons Collections vs Google Guava

1. Oversigt

I denne vejledning sammenligner vi to Java-baserede open source-biblioteker: Apache Commons og Google Guava. Begge biblioteker har et rigt funktionssæt med masser af hjælpeprogrammer, der hovedsagelig findes i samlingerne og I / O-området.

For kortfattethed beskriver vi her kun en håndfuld af de mest almindeligt anvendte fra samlingens ramme sammen med kodeeksempler. Vi ser også et resumé af deres forskelle.

Derudover Vi har en samling af artikler til et dybt dyk i forskellige commons og Guava-værktøjer.

2. En kort historie om de to biblioteker

Google Guava er et Google-projekt, der hovedsagelig er udviklet af organisationens ingeniører, selvom det nu er open source. Det Hovedmotivationen til at starte det var at inkludere generics introduceret i JDK 1.5 i Java Collections Framework, eller JCF, og forbedre dens kapacitet.

Siden starten har biblioteket udvidet sine muligheder og inkluderer nu grafer, funktionel programmering, rækkeviddeobjekter, caching og Snor manipulation.

Apache Commons startede som et Jakarta-projekt for at supplere kernens Java-samlinger-API og blev til sidst et projekt fra Apache Software Foundation. I årenes løb har det udvidet til et stort repertoire af genanvendelige Java-komponenter inden for forskellige andre områder, inklusive (men ikke begrænset til) billeddannelse, I / O, kryptografi, caching, netværk, validering og pooling af objekter.

Da dette er et open source-projekt, fortsætter udviklere fra Apache-samfundet med at tilføje til dette bibliotek for at udvide dets muligheder. Imidlertid, de tager stor omhu for at opretholde bagudkompatibilitet.

3. Maven-afhængighed

For at inkludere Guava skal vi tilføje dets afhængighed til vores pom.xml:

 com.google.guava guava 29.0-jre 

De nyeste versionoplysninger kan findes på Maven.

For Apache Commons er det lidt anderledes. Afhængigt af det værktøj, vi vil bruge, skal vi tilføje den ene. For eksempel til samlinger skal vi tilføje:

 org.apache.commons commons-collection4 4.4 

I vores kodeeksempler bruger vi fælles-samlinger4.

Lad os hoppe ind i den sjove del nu!

4. Tovejs kort

Kort, der er tilgængelige med deres nøgler såvel som værdier, er kendt som tovejskort. JCF har ikke denne funktion.

Lad os se, hvordan vores to teknologier tilbyder dem. I begge tilfælde tager vi et eksempel på ugedage for at få navnet på dagen givet sit nummer og omvendt.

4.1. Guava BiMap

Guava tilbyder en grænseflade - BiMap, som et tovejskort. Det kan instantieres med en af ​​dets implementeringer EnumBiMap, EnumHashBiMap, HashBiMap, eller ImmutableBiMap.

Her bruger vi HashBiMap:

BiMap daysOfWeek = HashBiMap.create ();

At udfylde det ligner ethvert kort i Java:

dageOfWeek.put (1, "mandag"); dageOfWeek.put (2, "tirsdag"); dageOfWeek.put (3, "onsdag"); dageOfWeek.put (4, "torsdag"); dageOfWeek.put (5, "fredag"); dageOfWeek.put (6, "lørdag"); dageOfWeek.put (7, "søndag");

Og her er nogle JUnit-tests for at bevise konceptet:

@Test offentlig ugyldighed givenBiMap_whenValue_thenKeyReturned () {assertEquals (Integer.valueOf (7), daysOfWeek.inverse (). Get ("Sunday")); } @ Test offentlig ugyldighed givenBiMap_whenKey_thenValueReturned () {assertEquals ("Tuesday", daysOfWeek.get (2)); }

4.2. Apache's BidiMap

Tilsvarende giver Apache os dets BidiMap grænseflade:

BidiMap daysOfWeek = nyt TreeBidiMap ();

Her bruger vi TreeBidiMap. Der er dog andre implementeringer, såsom DualHashBidiMap og DualTreeBidiMap såvel.

For at udfylde det kan vi sætte værdierne, som vi gjorde for BiMap over.

Dens anvendelse er også ret ens:

@Test offentlig ugyldighed givenBidiMap_whenValue_thenKeyReturned () {assertEquals (Integer.valueOf (7), daysOfWeek.inverseBidiMap (). Get ("Sunday")); } @ Test offentlig ugyldighed givenBidiMap_whenKey_thenValueReturned () {assertEquals ("Tuesday", daysOfWeek.get (2)); }

I et par enkle præstationstest, dette tovejskort halter bag sit Guava-modstykke kun i indsættelser. Det var meget hurtigere at hente nøgler såvel som værdier.

5. Kortnøgler til flere værdier

For en brugssag, hvor vi ønsker at kortlægge flere nøgler til forskellige værdier, såsom en indkøbskurvsamling til frugt og grøntsager, tilbyder de to biblioteker os unikke løsninger.

5.1. Guava MultiMap

Lad os først se, hvordan man starter og initialiserer MultiMap:

Multimap groceryCart = ArrayListMultimap.create (); groceryCart.put ("Frugter", "Æble"); groceryCart.put ("Frugter", "Druer"); groceryCart.put ("Frugter", "Jordbær"); groceryCart.put ("Grøntsager", "Spinat"); groceryCart.put ("Grøntsager", "Kål");

Derefter bruger vi et par JUnit-tests til at se det i aktion:

@Test offentlig ugyldighed givenMultiValuedMap_whenFruitsFetched_thenFruitsReturned () {List fruits = Arrays.asList ("Apple", "Druer", "Jordbær"); assertEquals (frugter, groceryCart.get ("Frugter")); } @ Test offentligt ugyldigt givenMultiValuedMap_whenVeggiesFetched_thenVeggiesReturned () {List veggies = Arrays.asList ("Spinat", "Cabbage"); assertEquals (veggies, groceryCart.get ("Grøntsager")); } 

Derudover MultiMap giver os muligheden for at fjerne en given post eller et helt sæt værdier fra kortet:

@Test offentlig ugyldighed givenMultiValuedMap_whenFuitsRemoved_thenVeggiesPreserved () {assertEquals (5, groceryCart.size ()); groceryCart.remove ("Frugter", "Æble"); assertEquals (4, groceryCart.size ()); groceryCart.removeAll ("Frugter"); assertEquals (2, groceryCart.size ()); }

Som vi kan se, fjernede vi her først Æble fra Frugter indstillet og derefter fjernet hele Frugter sæt.

5.2. Apache's MultiValuedMap

Lad os igen begynde med at starte en MultiValuedMap:

MultiValuedMap groceryCart = ny ArrayListValuedHashMap ();

Da udfyldning er det samme som vi så i det foregående afsnit, lad os hurtigt se på brugen:

@Test offentlig ugyldighed givenMultiValuedMap_whenFruitsFetched_thenFruitsReturned () {List fruits = Arrays.asList ("Apple", "Druer", "Jordbær"); assertEquals (frugter, groceryCart.get ("Frugter")); } @ Test offentligt ugyldigt givenMultiValuedMap_whenVeggiesFetched_thenVeggiesReturned () {List veggies = Arrays.asList ("Spinat", "Cabbage"); assertEquals (veggies, groceryCart.get ("Grøntsager")); }

Som vi kan se, er dens anvendelse også den samme!

I dette tilfælde har vi imidlertid ikke fleksibiliteten til at fjerne en enkelt post, f.eks Æble fra Frugter.Vi kan kun fjerne hele sættet af Frugter:

@Test offentlig ugyldighed givenMultiValuedMap_whenFuitsRemoved_thenVeggiesPreserved () {assertEquals (5, groceryCart.size ()); groceryCart.remove ("Frugter"); assertEquals (2, groceryCart.size ()); }

6. Kortlæg flere taster til en værdi

Her tager vi et eksempel på breddegrader og længdegrader, der skal kortlægges til respektive byer:

cityCoordinates.put ("40.7128 ° N", "74.0060 ° W", "New York"); cityCoordinates.put ("48.8566 ° N", "2.3522 ° E", "Paris"); cityCoordinates.put ("19.0760 ° N", "72.8777 ° E", "Mumbai");

Nu skal vi se, hvordan man opnår dette.

6.1. Guava Bord

Guava tilbyder sin Bord der opfylder ovenstående brugstilfælde:

Tabel cityCoordinates = HashBasedTable.create ();

Og her er nogle anvendelser, vi kan udlede ud af det:

@Test offentlig ugyldighed givenCoordinatesTable_whenFetched_thenOK () {Liste forventetLængder = Arrays.asList ("74.0060 ° W", "2.3522 ° E", "72.8777 ° E"); assertArrayEquals (expectLongitudes.toArray (), cityCoordinates.columnKeySet (). toArray ()); Liste forventede byer = Arrays.asList ("New York", "Paris", "Mumbai"); assertArrayEquals (expectCities.toArray (), cityCoordinates.values ​​(). toArray ()); assertTrue (cityCoordinates.rowKeySet (). indeholder ("48.8566 ° N")); }

Som vi kan se, kan vi få en Sæt visning af rækkerne, kolonnerne og værdierne.

Bord giver os også muligheden for at forespørge dens rækker eller kolonner.

Lad os overveje et filmbord for at demonstrere dette:

Tabelfilm = HashBasedTable.create (); films.put ("Tom Hanks", "Meg Ryan", "You've Got Mail"); films.put ("Tom Hanks", "Catherine Zeta-Jones", "The Terminal"); films.put ("Bradley Cooper", "Lady Gaga", "En stjerne er født"); films.put ("Keenu Reaves", "Sandra Bullock", "Speed"); films.put ("Tom Hanks", "Sandra Bullock", "Ekstremt højt og utroligt tæt");

Og her er nogle eksempler, selvforklarende søgninger, som vi kan gøre på vores filmBord:

@Test offentlig ugyldighed givenMoviesTable_whenFetched_thenOK () {assertEquals (3, film.row ("Tom Hanks"). Størrelse ()); assertEquals (2, film.kolonne ("Sandra Bullock"). størrelse ()); assertEquals ("En stjerne er født", films.get ("Bradley Cooper", "Lady Gaga")); assertTrue (film.containsValue ("Speed")); }

Imidlertid, Bord begrænser os til kun at kortlægge to nøgler til en værdi. Vi har endnu ikke et alternativ i Guava til at kortlægge mere end to nøgler til en enkelt værdi.

6.2. Apache's MultiKeyMap

Kommer tilbage til vores cityCoordinates eksempel, her er hvordan vi kan manipulere det ved hjælp af MultiKeyMap:

@Test offentlig ugyldighed givenCoordinatesMultiKeyMap_whenQueried_thenOK () {MultiKeyMap cityCoordinates = ny MultiKeyMap (); // udfyld med nøgler og værdier som tidligere vist Liste forventet længde = Arrays.asList ("72.8777 ° E", "2.3522 ° E", "74.0060 ° W"); Vis længdegrader = ny ArrayList (); cityCoordinates.forEach ((nøgle, værdi) -> {longitudes.add (key.getKey (1));}); assertArrayEquals (expectLongitudes.toArray (), longitudes.toArray ()); Liste forventede byer = Arrays.asList ("Mumbai", "Paris", "New York"); Liste byer = ny ArrayList (); cityCoordinates.forEach ((nøgle, værdi) -> {towns.add (værdi);}); assertArrayEquals (expectCities.toArray (), towns.toArray ()); }

Som vi kan se fra ovenstående kodestykke, for at komme til de samme påstande som for Guava Bord, vi måtte gentage os over MultiKeyMap.

Imidlertid, MultiKeyMap giver også muligheden for at kortlægge mere end to taster til en værdi. For eksempel giver det os muligheden for at kortlægge ugedage som hverdage eller weekender:

@Test offentligt ugyldigt givenDaysMultiKeyMap_whenFetched_thenOK () {dage = nyt MultiKeyMap (); dage.put ("mandag", "tirsdag", "onsdag", "torsdag", "fredag", "hverdag"); dage.put ("lørdag", "søndag", "weekend"); assertFalse (dage.get ("lørdag", "søndag"). er lig med ("hverdag")); }

7. Apache Commons-samlinger vs. Google Guava

I henhold til dets ingeniører, Google Guava blev født ud af behovet for at bruge generiske stoffer i biblioteket, som Apache Commons ikke tilbød. Det følger også samlingens API-krav til tee. En anden stor fordel er, at den er i aktiv udvikling med nye udgivelser, der ofte kommer ud.

Apache tilbyder dog en fordel, når det kommer til ydeevne, mens man henter en værdi fra en samling. Guava tager dog stadig kagen med hensyn til indsættelsestider.

Selvom vi kun sammenlignede API'erne for samlinger i vores kodeeksempler, Apache Commons som helhed tilbyder et meget større spektrum af funktioner sammenlignet med Guava.

8. Konklusion

I denne tutorial sammenlignede vi nogle af de funktioner, der tilbydes af Apache Commons og Google Guava, specifikt inden for området for samlinger.

Her skrabet vi blot overfladen af, hvad de to biblioteker har at tilbyde.

Desuden er det ikke en enten-eller sammenligning. Som vores kodeeksempler demonstrerede, der er funktioner, der er unikke for hver af de to, og der kan være situationer, hvor begge kan eksistere sammen.

Som altid er kildekoden tilgængelig på GitHub.


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