Apache Commons samlinger vs Google Guava

1. Oversikt

I denne opplæringen vil vi sammenligne to Java-baserte open source-biblioteker: Apache Commons og Google Guava. Begge bibliotekene har et rikt funksjonssett med mange verktøy-API-er, hovedsakelig i samlingene og I / O-området.

For kortfattethet vil vi bare beskrive en håndfull av de mest brukte fra samlingens rammeverk sammen med kodeeksempler. Vi ser også et sammendrag av forskjellene deres.

I tillegg vi har en samling av artikler for et dypdykk i forskjellige allmenninger og Guava-verktøy.

2. En kort historie om de to bibliotekene

Google Guava er et Google-prosjekt, hovedsakelig utviklet av organisasjonens ingeniører, selv om det har blitt åpen fra nå. De hovedmotivasjonen for å starte det var å inkludere generiske produkter introdusert i JDK 1.5 i Java Collections Framework, eller JCF, og forbedre dens evne.

Siden oppstarten har biblioteket utvidet funksjonene og inkluderer nå grafer, funksjonell programmering, rekkeviddeobjekter, hurtigbufring og String manipulasjon.

Apache Commons startet som et Jakarta-prosjekt for å supplere kjernen til Java-samlingen API og ble til slutt et prosjekt fra Apache Software Foundation. Gjennom årene har det utvidet seg til et stort repertoar av gjenbrukbare Java-komponenter på forskjellige andre områder, inkludert (men ikke begrenset til) bildebehandling, I / O, kryptografi, caching, nettverk, validering og objektpooling.

Siden dette er et åpen kildekodeprosjekt, fortsetter utviklere fra Apache-samfunnet å legge til i dette biblioteket for å utvide mulighetene. Derimot, de tar stor forsiktighet for å opprettholde bakoverkompatibilitet.

3. Maven avhengighet

For å inkludere Guava, må vi legge dens avhengighet til vår pom.xml:

 com.google.guava guava 29.0-jre 

Informasjonen om den nyeste versjonen finner du på Maven.

For Apache Commons er det litt annerledes. Avhengig av verktøyet vi vil bruke, må vi legge til den aktuelle. For samlinger må vi for eksempel legge til:

 org.apache.commons commons-collection4 4.4 

I kodeeksemplene bruker vi felles-samlinger4.

La oss hoppe inn i den morsomme delen nå!

4. Toveis kart

Kart som er tilgjengelige med nøklene, samt verdier, er kjent som toveiskart. JCF har ikke denne funksjonen.

La oss se hvordan våre to teknologier tilbyr dem. I begge tilfeller tar vi et eksempel på ukedagene for å få navnet på dagen gitt nummeret og omvendt.

4.1. Guava BiMap

Guava tilbyr et grensesnitt - BiMap, som et toveiskart. Det kan instantieres med en av implementeringene EnumBiMap, EnumHashBiMap, HashBiMap, eller ImmutableBiMap.

Her bruker vi HashBiMap:

BiMap daysOfWeek = HashBiMap.create ();

Å fylle det ligner på alle kart i Java:

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

Og her er noen JUnit-tester for å bevise konseptet:

@Test offentlig ugyldighet gittBiMap_whenValue_thenKeyReturned () {assertEquals (Integer.valueOf (7), daysOfWeek.inverse (). Get ("Sunday")); } @Test offentlig ugyldighet gittBiMap_whenKey_thenValueReturned () {assertEquals ("Tuesday", daysOfWeek.get (2)); }

4.2. Apache er BidiMap

Tilsvarende gir Apache oss sine BidiMap grensesnitt:

BidiMap daysOfWeek = nytt TreeBidiMap ();

Her bruker vi TreeBidiMap. Imidlertid er det andre implementeringer, for eksempel DualHashBidiMap og DualTreeBidiMap også.

For å fylle det, kan vi sette verdiene slik vi gjorde for BiMap ovenfor.

Bruken er også ganske lik:

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

I noen få enkle ytelsestester, dette toveiskartet heng etter Guava-motstykket bare i innsettinger. Det gikk mye raskere med å hente nøkler så vel som verdier.

5. Kartnøkler til flere verdier

For et brukstilfelle der vi ønsker å kartlegge flere nøkler til forskjellige verdier, for eksempel en dagligvaresamling for frukt og grønnsaker, tilbyr de to bibliotekene oss unike løsninger.

5.1. Guava MultiMap

La oss først se hvordan du kan starte og initialisere MultiMap:

Multimap groceryCart = ArrayListMultimap.create (); groceryCart.put ("Frukt", "Apple"); groceryCart.put ("Frukt", "Druer"); groceryCart.put ("Frukt", "Jordbær"); groceryCart.put ("Grønnsaker", "Spinat"); groceryCart.put ("Grønnsaker", "Kål");

Deretter bruker vi et par JUnit-tester for å se det i aksjon:

@Test offentlig ugyldig gittMultiValuedMap_whenFruitsFetched_thenFruitsReturned () {List fruits = Arrays.asList ("Apple", "Grapes", "Strawberries"); assertEquals (frukt, groceryCart.get ("Frukt")); } @Test offentlig ugyldig gittMultiValuedMap_whenVeggiesFetched_thenVeggiesReturned () {List veggies = Arrays.asList ("Spinat", "Cabbage"); assertEquals (veggies, groceryCart.get ("Grønnsaker")); } 

I tillegg MultiMap gir oss muligheten til å fjerne en gitt oppføring eller et helt sett med verdier fra kartet:

@Test offentlig ugyldighet gittMultiValuedMap_whenFuitsRemoved_thenVeggiesPreserved () {assertEquals (5, groceryCart.size ()); groceryCart.remove ("Frukt", "Eple"); assertEquals (4, groceryCart.size ()); groceryCart.removeAll ("Frukt"); assertEquals (2, groceryCart.size ()); }

Som vi kan se, fjernet vi her først eple fra Frukt sett og fjernet deretter hele Frukt sett.

5.2. Apache er MultiValuedMap

Igjen, la oss begynne med å starte en MultiValuedMap:

MultiValuedMap groceryCart = ny ArrayListValuedHashMap ();

Siden befolkningen er den samme som vi så i forrige avsnitt, la oss raskt se på bruken:

@Test offentlig ugyldig gittMultiValuedMap_whenFruitsFetched_thenFruitsReturned () {List fruits = Arrays.asList ("Apple", "Grapes", "Strawberries"); assertEquals (frukt, groceryCart.get ("Frukt")); } @Test offentlig ugyldig gittMultiValuedMap_whenVeggiesFetched_thenVeggiesReturned () {List veggies = Arrays.asList ("Spinat", "Cabbage"); assertEquals (veggies, groceryCart.get ("Grønnsaker")); }

Som vi kan se, er bruken også den samme!

I dette tilfellet har vi imidlertid ikke fleksibiliteten til å fjerne en enkelt oppføring, for eksempel eple fra Frukt.Vi kan bare fjerne hele settet med Frukt:

@Test offentlig ugyldighet gittMultiValuedMap_whenFuitsRemoved_thenVeggiesPreserved () {assertEquals (5, groceryCart.size ()); groceryCart.remove ("Frukt"); assertEquals (2, groceryCart.size ()); }

6. Kartlegg flere nøkler til en verdi

Her tar vi et eksempel på breddegrader og lengdegrader som skal kartlegges til respektive byer:

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

Nå får vi se hvordan vi kan oppnå dette.

6.1. Guava Bord

Guava tilbyr sin Bord som tilfredsstiller brukssaken ovenfor:

Tabell cityCoordinates = HashBasedTable.create ();

Og her er noen bruksområder vi kan utlede av det:

@Test offentlig ugyldighet givenCoordinatesTable_whenFetched_thenOK () {List expectedLongitudes = Arrays.asList ("74.0060 ° W", "2.3522 ° E", "72.8777 ° E"); assertArrayEquals (expectLongitudes.toArray (), cityCoordinates.columnKeySet (). toArray ()); Liste forventet byer = Arrays.asList ("New York", "Paris", "Mumbai"); assertArrayEquals (expectCities.toArray (), cityCoordinates.values ​​(). toArray ()); assertTrue (cityCoordinates.rowKeySet (). inneholder ("48.8566 ° N")); }

Som vi kan se, kan vi få en Sett visning av radene, kolonnene og verdiene.

Bord gir oss også muligheten til å spørre om rader eller kolonner.

La oss vurdere et filmbord for å demonstrere dette:

Bordfilmer = HashBasedTable.create (); movies.put ("Tom Hanks", "Meg Ryan", "You've Got Mail"); movies.put ("Tom Hanks", "Catherine Zeta-Jones", "The Terminal"); movies.put ("Bradley Cooper", "Lady Gaga", "A Star is Born"); movies.put ("Keenu Reaves", "Sandra Bullock", "Speed"); movies.put ("Tom Hanks", "Sandra Bullock", "Ekstremt høyt og utrolig nært");

Og her er noen eksempler på, selvforklarende søk som vi kan gjøre på vår filmerBord:

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

Derimot, Bord begrenser oss til å kartlegge bare to nøkler til en verdi. Vi har ikke et alternativ ennå i Guava for å kartlegge mer enn to nøkler til en enkelt verdi.

6.2. Apache er MultiKeyMap

Kommer tilbake til vår cityCoordinates for eksempel, her er hvordan vi kan manipulere det ved hjelp av MultiKeyMap:

@Test offentlig ugyldig gittCoordinatesMultiKeyMap_whenQueried_thenOK () {MultiKeyMap cityCoordinates = ny MultiKeyMap (); // fylle med nøkler og verdier som vist tidligere Liste forventet lengdegrad = Arrays.asList ("72.8777 ° Ø", "2.3522 ° Ø", "74.0060 ° W"); List lengdegrader = ny ArrayList (); cityCoordinates.forEach ((key, value) -> {longitudes.add (key.getKey (1));}); assertArrayEquals (expectLongitudes.toArray (), longitudes.toArray ()); Liste forventet byer = Arrays.asList ("Mumbai", "Paris", "New York"); Liste byer = ny ArrayList (); cityCoordinates.forEach ((nøkkel, verdi) -> {towns.add (verdi);}); assertArrayEquals (expectedCities.toArray (), towns.toArray ()); }

Som vi kan se fra kodebiten ovenfor, for å komme til de samme påstandene som for Guava Bord, vi måtte gjenta over MultiKeyMap.

Derimot, MultiKeyMap gir også muligheten til å kartlegge mer enn to nøkler til en verdi. For eksempel gir det oss muligheten til å kartlegge ukedager som hverdager eller helger:

@Test offentlig ugyldighet givenDaysMultiKeyMap_whenFetched_thenOK () {dager = ny MultiKeyMap (); days.put ("mandag", "tirsdag", "onsdag", "torsdag", "fredag", "ukedag"); days.put ("lørdag", "søndag", "helg"); assertFalse (dager.get ("lørdag", "søndag"). tilsvarer ("ukedag")); }

7. Apache Commons-samlinger vs. Google Guava

I henhold til ingeniørene, Google Guava ble født av behovet for å bruke generiske stoffer i biblioteket, som Apache Commons ikke tilbød. Den følger også kravene til samlingens API til tee. En annen stor fordel er at den er i aktiv utvikling med nye utgivelser som ofte kommer ut.

Apache tilbyr imidlertid en fordel når det gjelder ytelse mens du henter en verdi fra en samling. Guava tar likevel kaken, når det gjelder innsettingstider.

Selv om vi bare sammenlignet APIene til samlingene i kodeeksemplene våre, Apache Commons som helhet tilbyr et mye større utvalg av funksjoner sammenlignet med Guava.

8. Konklusjon

I denne opplæringen sammenlignet vi noe av funksjonaliteten som tilbys av Apache Commons og Google Guava, spesielt innen samlingsrammen.

Her skrapte vi bare overflaten av det de to bibliotekene har å tilby.

Videre er det ikke en enten-eller sammenligning. Som kodeprøvene våre demonstrerte, det er funksjoner som er unike for hver av de to, og det kan være situasjoner der begge kan eksistere sammen.

Som alltid er kildekoden tilgjengelig på GitHub.