En introduksjon til Apache Commons Lang 3

1. Oversikt

Apache Commons Lang 3-biblioteket er en populær, fullverdig pakke med verktøyklasser, rettet mot å utvide funksjonaliteten til Java API.

Bibliotekets repertoar er ganske rikt, alt fra streng-, array- og tallmanipulering, refleksjon og samtidighet til implementeringer av flere bestilte datastrukturer, som par og tripler (generelt kjent som tupler).

I denne veiledningen, vi tar et dypdykk i bibliotekets mest nyttige nytteklasser.

2. Maven-avhengigheten

For å komme i gang med Apache Commons Lang 3, må vi som vanlig legge til Maven-avhengigheten:

 org.apache.commons commons-lang3 3.8 

3. Den StringUtils Klasse

Den første nytteklassen som vi skal dekke i denne innledende sammendraget er StringUtils.

Som navnet antyder, StringUtils tillater oss å utføre en haug med null-safe stringer operasjoner som utfyller / utvider de som java.lang.Streng gir ut av esken.

La oss begynne å vise settet med verktøymetoder som utfører flere kontroller på en gitt streng, for eksempel å avgjøre om streng er blank, tom, med små bokstaver, med store bokstaver, alfanumeriske og så videre:

@Test offentlig ugyldig når CalledisBlank_thenCorrect () {assertThat (StringUtils.isBlank ("")). IsTrue (); } @Test offentlig ugyldig nårCalledisEmpty_thenCorrect () {assertThat (StringUtils.isEmpty ("")). IsTrue (); } @Test offentlig ugyldig nårCalledisAllLowerCase_thenCorrect () {assertThat (StringUtils.isAllLowerCase ("abd")). IsTrue (); } @Test offentlig ugyldig når CalledisAllUpperCase_thenCorrect () {assertThat (StringUtils.isAllUpperCase ("ABC")). IsTrue (); } @Test offentlig ugyldig nårCalledisMixedCase_thenCorrect () {assertThat (StringUtils.isMixedCase ("abC")). IsTrue (); } @Test offentlig ugyldig nårCalledisAlpha_thenCorrect () {assertThat (StringUtils.isAlpha ("abc")). IsTrue (); } @Test offentlig ugyldig nårCalledisAlphanumeric_thenCorrect () {assertThat (StringUtils.isAlphanumeric ("abc123")). IsTrue (); } 

Selvfølgelig, den StringUtils klasse implementerer mange andre metoder, som vi har utelatt her for enkelhets skyld.

For noen andre tilleggsmetoder som sjekker eller bruker noen form for konverteringsalgoritme til en gitt streng, sjekk denne opplæringen.

De som vi har dekket over er veldig greie, så enhetstestene bør være selvforklarende.

4. Den ArrayUtils Klasse

De ArrayUtils klasse implementerer en rekke verktøymetoder som lar oss behandle og sjekke matriser i mange forskjellige former og former.

La oss starte med de to overbelastede implementeringene av toString () metode, som returnerer a streng representasjon av det gitte array og en spesifikk streng når array er null:

@Test offentlig ugyldig nårCalledtoString_thenCorrect () {String [] array = {"a", "b", "c"}; assertThat (ArrayUtils.toString (array)) .isEqualTo ("{a, b, c}"); } @Test offentlig ugyldig nårCalledtoStringIfArrayisNull_thenCorrect () {assertThat (ArrayUtils.toString (null, "Array is null")) .isEqualTo ("Array is null"); } 

Deretter har vi hasCode () og å kartlegge() metoder.

Førstnevnte genererer en tilpasset hashCode-implementering for en matrise, mens sistnevnte konverterer en array til en Kart:

@Test offentlig ugyldig nårCalledhashCode_thenCorrect () {String [] array = {"a", "b", "c"}; assertThat (ArrayUtils.hashCode (array)) .isEqualTo (997619); } @Test offentlig ugyldig nårCalledtoMap_thenCorrect () {String [] [] array = {{"1", "one",}, {"2", "two",}, {"3", "three"}}; Kartkart = nytt HashMap (); map.put ("1", "one"); map.put ("2", "two"); map.put ("3", "tre"); assertThat (ArrayUtils.toMap (array)) .isEqualTo (kart); }

Til slutt, la oss se på isSameLength () og oversikt over() metoder.

Førstnevnte brukes til å sjekke om to matriser har samme lengde, og sistnevnte for å få indeksen til et gitt element:

@Test offentlig ugyldig nårCalledisSameLength_thenCorrect () {int [] array1 = {1, 2, 3}; int [] array2 = {1, 2, 3}; assertThat (ArrayUtils.isSameLength (array1, array2)) .isTrue (); } @Test offentlig ugyldig nårCalledIndexOf_thenCorrect () {int [] array = {1, 2, 3}; assertThat (ArrayUtils.indexOf (array, 1, 0)) .isEqualTo (0); } 

Som med StringUtils klasse, ArrayUtils implementere mange flere tilleggsmetoder. Du kan lære mer om dem i denne opplæringen.

I dette tilfellet har vi bare vist frem de mest representative.

5. Den NumberUtils Klasse

En annen viktig komponent i Apache Commons Lang 3 er NumberUtils-klassen.

Som forventet, klassen gir et omfattende antall bruksmetoder, rettet mot behandling og manipulering av numeriske typer.

La oss se på de overbelastede implementeringene av sammenligne() metode, som sammenligner likheten mellom forskjellige primitiver, som f.eks int og lang:

@Test offentlig ugyldig nårCalledcompareWithIntegers_thenCorrect () {assertThat (NumberUtils.compare (1, 1)) .isEqualTo (0); } @Test offentlig ugyldig nårCalledcompareWithLongs_thenCorrect () {assertThat (NumberUtils.compare (1L, 1L)) .isEqualTo (0); }

I tillegg finnes det implementeringer av sammenligne() som fungerer byte og kort, som fungerer veldig likt eksemplene ovenfor.

Neste i denne anmeldelsen er createNumber () og isDigit () metoder.

Den første lar oss lage en numerisk representasjon av a streng, mens den andre sjekker om a streng består bare av sifre:

@Test offentlig ugyldig nårCalledcreateNumber_thenCorrect () {assertThat (NumberUtils.createNumber ("123456")) .isEqualTo (123456); } @Test offentlig ugyldig når CalledisDigits_thenCorrect () {assertThat (NumberUtils.isDigits ("123456")). IsTrue (); } 

Når det gjelder å finne blandings- og maksverdiene til en matrise som leveres, blir NumberUtils klasse gir sterk støtte for disse operasjonene gjennom overbelastede implementeringer av min () og maks () metoder:

@Test offentlig ugyldig nårCalledmaxwithIntegerArray_thenCorrect () {int [] array = {1, 2, 3, 4, 5, 6}; assertThat (NumberUtils.max (array)) .isEqualTo (6); } @Test offentlig ugyldig nårCalledminwithIntegerArray_thenCorrect () {int [] array = {1, 2, 3, 4, 5, 6}; assertThat (NumberUtils.min (array)). erEqualTo (1); } @Test offentlig ugyldig nårCalledminwithByteArray_thenCorrect () {byte [] array = {1, 2, 3, 4, 5, 6}; assertThat (NumberUtils.min (array)) .isEqualTo ((byte) 1); }

6. De Brøkdel Klasse

Å jobbe med brøker er alt i orden når vi bruker en penn og et stykke papir. Men må vi gå gjennom kompleksiteten i denne prosessen når vi skriver kode? Ikke egentlig.

De Brøkdel klasse gjør det å legge til, trekke fra og multiplisere brøker i en lek:

@Test offentlig ugyldig nårCalledgetFraction_thenCorrect () {assertThat (Fraction.getFraction (5, 6)). IsInstanceOf (Fraction.class); } @Test offentlig ugyldighet givenTwoFractionInstances_whenCalledadd_thenCorrect () {Fraksjon fraksjon1 = Fraksjon.getFraksjons (1, 4); Brøkdel fraksjon2 = Fraksjon.getFraksjon (3, 4); assertThat (fraksjon1.add (fraksjon2) .toString ()). erEqualTo ("1/1"); } @Test offentlig ugyldig givenTwoFractionInstances_whenCalledsubstract_thenCorrect () {Fraksjon fraksjon1 = Fraksjon.getFraksjons (3, 4); Brøkdel fraksjon2 = Fraksjon.getFraksjon (1, 4); assertThat (brøkdel1.subtraksjon (brøkdel2) .tilString ()). erEqualTo ("1/2"); } @Test offentlig ugyldighet givenTwoFractionInstances_whenCalledmultiply_thenCorrect () {Fraksjon fraksjon1 = Fraksjon.getFraksjons (3, 4); Brøkdel fraksjon2 = Fraksjon.getFraksjon (1, 4); assertThat (fraction1.multiplyBy (fraction2) .toString ()). isEqualTo ("3/16"); }

Selv om operasjoner med brøker ikke er den hyppigste oppgaven vi må takle i vårt daglige utviklingsarbeid, er Brøkdel klasse gir verdifull støtte for å utføre disse operasjonene på en enkel måte.

7. Den SystemUtils Klasse

Noen ganger må vi skaffe oss litt dynamisk informasjon om forskjellige egenskaper og variabler til den underliggende Java-plattformen eller operativsystemet.

Apache Commons Lang 3 tilbyr SystemUtils-klasse for å oppnå dette på en smertefri måte.

La oss for eksempel vurdere getJavaHome (), getUserHome () og isJavaVersionAtLeast () metoder:

@Test offentlig ugyldig nårCalledgetJavaHome_thenCorrect () {assertThat (SystemUtils.getJavaHome ()) .isEqualTo (new File ("path / to / java / jdk")); } @Test offentlig ugyldig nårCalledgetUserHome_thenCorrect () {assertThat (SystemUtils.getUserHome ()) .isEqualTo (ny fil ("sti / til / bruker / hjem")); } @Test offentlig ugyldig nårCalledisJavaVersionAtLeast_thenCorrect () {assertThat (SystemUtils.isJavaVersionAtLeast (JavaVersion.JAVA_RECENT)). IsTrue (); }

Det er noen ekstra verktøymetoder som SystemUtils klasse redskaper. Vi har utelatt dem for å holde eksemplene korte.

8. Lazy Initialization and Builder Classes

En av Apache Commons Lang 3s mest tiltalende fasetter er implementeringen av noen kjente designmønstre, inkludert lat initialisering og byggemønstre.

La oss for eksempel si at vi har skapt en kostbar Bruker klasse (ikke vist for kortfattethet), og ønsker å utsette instantiseringen til den virkelig er nødvendig.

I et slikt tilfelle er alt vi trenger å gjøre å utvide den parametriserte abstrakte klassen LazyInitializer og overstyre dens initialisere () metode:

offentlig klasse UserInitializer utvider LazyInitializer {@ Override protection User initialize () {return new User ("John", "[email protected]"); }}

Nå, hvis vi vil bli dyre Bruker objekt når det er nødvendig, vi bare kaller UserInitializer får () metode:

@Test offentlig ugyldig når Calledget_thenCorrect () kaster ConcurrentException {UserInitializer userInitializer = ny UserInitializer (); assertThat (userInitializer.get ()). erInstanceOf (User.class); }

De få() metoden er en implementering av dobbeltsjekkidiomet (trådsikkert) for et forekomstfelt, som spesifisert i Joshua Blochs “Effective Java”, artikkel 71:

privat flyktig brukerinstans; Bruker får () {if (forekomst == null) {synkronisert (dette) {hvis (forekomst == null) forekomst = ny bruker ("John", "[e-postbeskyttet]"); }}} returner forekomst; }

I tillegg implementerer Apache Commons Lang 3 HashCodeBuilder-klassen, som lar oss generere hashCode () implementeringer ved å forsyne byggherren med forskjellige parametere, basert på et typisk flytende API:

@Test offentlig ugyldig nårCalledtoHashCode_thenCorrect () {int hashcode = new HashCodeBuilder (17, 37) .append ("John") .append ("[email protected]") .toHashCode (); assertThat (hashcode) .isEqualTo (1269178828); }

Vi kan gjøre noe lignende med BasicThreadFactory klasse, og lag daemon-tråder med et navngivningsmønster og en prioritet:

@Test offentlig ugyldig nårCalledBuilder_thenCorrect () {BasicThreadFactory fabrikk = ny BasicThreadFactory.Builder () .namingPattern ("workerthread-% d") .daemon (true) .priority (Thread.MAX_PRIORITY) .build (); assertThat (fabrikk) .isInstanceOf (BasicThreadFactory.class); }

9. The ConstructorUtils Klasse

Reflection er en førsteklasses borger i Apache Commons Lang 3.

Biblioteket inkluderer flere refleksjonsklasser, som lar oss reflekterende få tilgang til og manipulere klassefelt og metoder.

La oss for eksempel si at vi har implementert en naiv Bruker domeneklasse:

offentlig klasse bruker {privat strengnavn; privat streng e-post; // standard konstruktører / getters / setters / toString}

Forutsatt at den parameteriserte konstruktøren er offentlig, kan vi enkelt få tilgang til den med ConstructorUtils klasse:

@Test offentlig ugyldig nårCalledgetAccessibleConstructor_thenCorrect () {assertThat (ConstructorUtils .getAccessibleConstructor (User.class, String.class, String.class)) .isInstanceOf (Constructor.class); } 

Alternativt til standard klasse instantiering via konstruktører, kan vi reflekterende lage Bruker tilfeller ved å bare ringe påkalleConstructor () og påkalleExactConstructor () metoder:

@Test offentlig ugyldig når CalledinvokeConstructor_thenCorrect () kaster unntak {assertThat (ConstructorUtils.invokeConstructor (User.class, "name", "email")) .isInstanceOf (User.class); } @Test offentlig ugyldig når CalledinvokeExactConstructor_thenCorrect () kaster Unntak {String [] args = {"name", "email"}; Klasse [] parameterTypes = {String.class, String.class}; assertThat (ConstructorUtils.invokeExactConstructor (User.class, args, parameterTypes)) .isInstanceOf (User.class); } 

10. The FieldUtils Klasse

På samme måte, vi kan bruke metodene til FieldUtils klasse for reflekterende lesing / skriving av feltfelt.

La oss anta at vi ønsker å få et felt av Bruker klasse, eller til slutt et felt som klassen arver fra en superklasse.

I et slikt tilfelle kan vi påberope oss getField () metode:

@Test offentlig annullert nårCalledgetField_thenCorrect () {assertThat (FieldUtils.getField (User.class, "name", true) .getName ()) .isEqualTo ("name"); } 

Alternativt hvis vi ønsker å bruke et mer restriktivt refleksjonsomfang, og bare få et felt erklært i Bruker klasse, og ikke arvet fra en superklasse, vi bruker bare getDeclaredField () metode:

@Test offentlig ugyldig nårCalledgetDeclaredFieldForceAccess_thenCorrect () {assertThat (FieldUtils.getDeclaredField (User.class, "name", true) .getName ()) .isEqualTo ("name"); }

I tillegg kan vi bruke getAllFields () metode for å få antall felt i den reflekterte klassen, og skriv en verdi til et deklarert felt eller et felt definert opp i et hierarki med writeField () og writeDeclaredField () metoder:

@Test offentlig ugyldig nårCalledgetAllFields_thenCorrect () {assertThat (FieldUtils.getAllFields (User.class) .length) .isEqualTo (2); } @Test offentlig ugyldig når CalledwriteField_thenCorrect () kaster IllegalAccessException {FieldUtils.writeField (bruker, "navn", "Julie", sant); assertThat (FieldUtils.readField (bruker, "navn", sant)) .isEqualTo ("Julie"); } @Test offentlig ugyldighet gittFieldUtilsClass_whenCalledwriteDeclaredField_thenCorrect () kaster IllegalAccessException {FieldUtils.writeDeclaredField (bruker, "navn", "Julie", sant); assertThat (FieldUtils.readField (bruker, "navn", sant)) .isEqualTo ("Julie"); }

11. The MethodUtils Klasse

På samme måte kan vi bruke refleksjon over klassemetoder med MethodUtils klasse.

I dette tilfellet er synligheten til Bruker klasse' getName () metoden er offentlig. Så vi kan få tilgang til den med getAccessibleMethod () metode:

@Test offentlig ugyldig nårCalledgetAccessibleMethod_thenCorrect () {assertThat (MethodUtils.getAccessibleMethod (User.class, "getName")) .isInstanceOf (Method.class); } 

Når det gjelder reflekterende påkallende metoder, kan vi bruke påkalleExactMethod () og påkalleMetode () metoder:

@Test offentlig ugyldig når CalledinvokeExactMethod_thenCorrect () kaster unntak {assertThat (MethodUtils.invokeExactMethod (ny bruker ("John", "[email protected]"), "getName")) .isEqualTo ("John"); } @Test offentlig ugyldig når CalledinvokeMethod_thenCorrect () kaster unntak {User user = new User ("John", "[email protected]"); Objektmetode = MethodUtils.invokeMethod (bruker, sann, "setName", "John"); assertThat (user.getName ()). isEqualTo ("John"); }

12. The MutableObject Klasse

Selv om uforanderlighet er en nøkkelfunksjon i god objektorientert programvare som vi burde som standard i alle mulige tilfeller, dessverre noen ganger trenger vi å håndtere foranderlige gjenstander.

Dessuten krever oppretting av mutable klasser mye kokerplatekode, som kan genereres av de fleste IDEer via automatisk genererte settere.

For dette formål tilbyr Apache Commons Lang 3 MutableObject klasse, en enkel innpakningsklasse for å lage foranderlige objekter med minimalt oppstyr:

@BeforeClass offentlig statisk ugyldighet setUpMutableObject () {mutableObject = new MutableObject ("Initial value"); } @Test offentlig ugyldig nårCalledgetValue_thenCorrect () {assertThat (mutableObject.getValue ()). IsInstanceOf (String.class); } @Test offentlig ugyldig nårCalledsetValue_thenCorrect () {mutableObject.setValue ("Another value"); assertThat (mutableObject.getValue ()). isEqualTo ("Another value"); } @Test offentlig ugyldig nårCalledtoString_thenCorrect () {assertThat (mutableObject.toString ()). IsEqualTo ("Another value"); } 

Dette er selvfølgelig bare et eksempel på hvordan du bruker MutableObject klasse.

Som tommelfingerregel, vi bør alltid streve for å skape uforanderlige klasser, eller i verste fall bare gi det nødvendige nivået av mutabilitet.

13. The MutablePair Klasse

Interessant nok gir Apache Commons Lang 3 sterk støtte for tupler, i form av par og tredobler.

La oss anta at vi trenger å lage et foranderlig par bestilte elementer.

I et slikt tilfelle vil vi bruke MutablePair klasse:

privat statisk MutablePair mutablePair; @BeforeClass offentlig statisk ugyldighet setUpMutablePairInstance () {mutablePair = new MutablePair ("leftElement", "rightElement"); } @Test offentlig ugyldig nårCalledgetLeft_thenCorrect () {assertThat (mutablePair.getLeft ()). IsEqualTo ("leftElement"); } @Test offentlig ugyldig nårCalledgetRight_thenCorrect () {assertThat (mutablePair.getRight ()). IsEqualTo ("rightElement"); } @Test offentlig ugyldig nårCalledsetLeft_thenCorrect () {mutablePair.setLeft ("newLeftElement"); assertThat (mutablePair.getLeft ()). isEqualTo ("newLeftElement"); } 

Den mest relevante det er verdt å understreke her er klassens rene API.

Det lar oss sette og få tilgang til venstre og høyre gjenstander pakket av paret gjennom standard settere / getters.

14. The Uforanderlig par Klasse

Ikke overraskende er det også en uforanderlig motstykkeimplementering av MutablePair klasse, kalt Uforanderlig par:

privat statisk ImmutablePair immutablePair = ny ImmutablePair ("leftElement", "rightElement"); @Test offentlig ugyldig nårCalledgetLeft_thenCorrect () {assertThat (immutablePair.getLeft ()). IsEqualTo ("leftElement"); } @Test offentlig ugyldig nårCalledgetRight_thenCorrect () {assertThat (immutablePair.getRight ()). IsEqualTo ("rightElement"); } @Test offentlig ugyldig nårCalledof_thenCorrect () {assertThat (ImmutablePair.of ("leftElement", "rightElement")) .isInstanceOf (ImmutablePair.class); } @Test (forventet = UnsupportedOperationException.class) offentlig ugyldig nårCalledSetValue_thenThrowUnsupportedOperationException () {immutablePair.setValue ("newValue"); } 

Som vi kan forvente fra en uforanderlig klasse, ethvert forsøk på å endre parets interne tilstand gjennom setValue () metoden vil resultere i å kaste en Ikke-støttetOperationException unntak.

15. De Trippel Klasse

Den siste nytteklassen som vil se på her er Trippel.

Ettersom klassen er abstrakt, kan vi skape Trippel tilfeller ved å bruke av() statisk fabrikkmetode:

@BeforeClass offentlig statisk ugyldig setUpTripleInstance () {triple = Triple.of ("leftElement", "middleElement", "rightElement"); } @Test offentlig ugyldig nårCalledgetLeft_thenCorrect () {assertThat (triple.getLeft ()). IsEqualTo ("leftElement"); } @Test offentlig ugyldig nårCalledgetMiddle_thenCorrect () {assertThat (triple.getMiddle ()). IsEqualTo ("middleElement"); } @Test offentlig ugyldig nårCalledgetRight_thenCorrect () {assertThat (triple.getRight ()). IsEqualTo ("rightElement"); }

Det er også konkrete implementeringer for både foranderlige og uforanderlige tripler, gjennom MutableTriple og ImmutableTriple klasser.

Vi kan opprette deres forekomster via parametriserte konstruktører, i stedet for med en statisk fabrikkmetode.

I dette tilfellet hopper vi bare over dem, da API-ene deres ser veldig ut som de MutablePair og Uforanderlig par klasser.

16. Konklusjon

I denne opplæringen tok vi en grundig titt på noen av de mest nyttige verktøyklassene som Apache Commons Lang 3 gir av hyllen .

Biblioteket implementerer mange andre nytteklasser som er verdt å se på. Her har vi nettopp vist frem de mest nyttige, basert på et ganske meningsfullt kriterium.

For fullstendig API-bibliotek, vennligst sjekk de offisielle Javadocs.

Som vanlig er alle kodeeksemplene som vises i denne opplæringen tilgjengelig på GitHub.


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