Bevezetés az Apache Commons Lang 3-ba

1. Áttekintés

Az Apache Commons Lang 3 könyvtár egy népszerű, teljes funkcionalitású segédprogramosztály-csomag, amelynek célja a Java API funkcionalitásának bővítése.

A könyvtár repertoárja meglehetősen gazdag, kezdve a karakterláncoktól, tömböktől és számoktól, a reflexiótól és a párhuzamosságtól kezdve számos rendezett adatstruktúra megvalósításáig, például párok és hármasok (általában párosok).

Ebben az oktatóanyagban mélyen megmártózunk a könyvtár leghasznosabb segédprogramjain.

2. A Maven-függőség

Szokás szerint az Apache Commons Lang 3 használatának megkezdéséhez először hozzá kell adnunk a Maven-függőséget:

 org.apache.commons commons-lang3 3.8 

3. Az StringUtils Osztály

Az első hasznossági osztály, amellyel ebben a bevezető körben foglalkozunk, az StringUtils.

Ahogy a neve is mutatja, StringUtils lehetővé teszi számunkra, hogy végezzünk egy csomó null-biztonságos s-ttrings műveletek, amelyek kiegészítik / kiterjesztik azokat, amelyek java.lang.String biztosítja a dobozból.

Kezdjük bemutatni a hasznossági módszerek halmazát, amelyek több ellenőrzést hajtanak végre egy adott esetben húr, például annak meghatározása, hogy a húr üres, üres, kisbetűs, nagybetűs, alfanumerikus és így tovább:

@Test public void whenCalledisBlank_thenCorrect () {assertThat (StringUtils.isBlank ("")). IsTrue (); } @Test public void whenCalledisEmpty_thenCorrect () {assertThat (StringUtils.isEmpty ("")). IsTrue (); } @Test public void whenCalledisAllLowerCase_thenCorrect () {assertThat (StringUtils.isAllLowerCase ("abd")). IsTrue (); } @Test public void whenCalledisAllUpperCase_thenCorrect () {assertThat (StringUtils.isAllUpperCase ("ABC")). IsTrue (); } @Test public void whenCalledisMixedCase_thenCorrect () {assertThat (StringUtils.isMixedCase ("abC")). IsTrue (); } @Test public void whenCalledisAlpha_thenCorrect () {assertThat (StringUtils.isAlpha ("abc")). IsTrue (); } @Test public void whenCalledisAlphanumeric_thenCorrect () {assertThat (StringUtils.isAlphanumeric ("abc123")). IsTrue (); } 

Természetesen a StringUtils osztály számos más módszert alkalmaz, amelyeket az egyszerűség kedvéért itt kihagytunk.

Néhány további módszer esetében, amely ellenőrzi vagy alkalmazza az átalakítás algoritmusát az adott típushoz húr, kérjük, ellenőrizze ezt az oktatóanyagot.

A fentiekben bemutatottak valóban egyszerűek, ezért az egységteszteknek maguktól értetődőnek kell lenniük.

4. A ArrayUtils Osztály

A ArrayUtils osztály végrehajt egy sor segédprogramot, amelyek lehetővé teszik számunkra a tömbök sokféle alakban és formában történő feldolgozását és ellenőrzését.

Kezdjük a következő két túlterhelt megvalósításával a toString () metódus, amely a húr az adott ábrázolása sor és egy konkrét húr amikor az sor nulla:

@Test public void whenCalledtoString_thenCorrect () {String [] tömb = {"a", "b", "c"}; assertThat (ArrayUtils.toString (tömb)) .isEqualTo ("{a, b, c}"); } @Test public void whenCalledtoStringIfArrayisNull_thenCorrect () {assertThat (ArrayUtils.toString (null, "A tömb null")) .isEqualTo ("A tömb null"); } 

Ezután megvan a hasCode () és térképre() mód.

Az előbbi létrehoz egy egyedi hashCode implementációt egy sor, míg utóbbi átalakítja az an-t sor a Térkép:

@Test public void whenCalledhashCode_thenCorrect () {String [] tömb = {"a", "b", "c"}; assertThat (ArrayUtils.hashCode (tömb)) .isEqualTo (997619); } @Test public void whenCalledtoMap_thenCorrect () {String [] [] tömb = {{"1", "egy",}, {"2", "kettő",}, {"3", "három"}}; Térképtérkép = új HashMap (); map.put ("1", "egy"); map.put ("2", "kettő"); map.put ("3", "három"); assertThat (ArrayUtils.toMap (tömb)) .isEqualTo (térkép); }

Végül nézzük meg a isSameLength () és indexe() mód.

Az előbbit annak ellenőrzésére használják, hogy két tömb azonos hosszúságú-e, az utóbbit pedig egy adott elem indexének lekérésére:

@Test public void whenCalledisSameLength_thenCorrect () {int [] tömb1 = {1, 2, 3}; int [] tömb2 = {1, 2, 3}; assertThat (ArrayUtils.isSameLength (tömb1, tömb2)) .isTrue (); } @Test public void whenCalledIndexOf_thenCorrect () {int [] tömb = {1, 2, 3}; assertThat (ArrayUtils.indexOf (tömb, 1, 0)) .isEqualTo (0); } 

Mint a StringUtils osztály, ArrayUtils sokkal több további módszert kell megvalósítani. Ebben az oktatóanyagban többet megtudhat róluk.

Ebben az esetben csak a legreprezentatívabbakat mutattuk be.

5. A NumberUtils Osztály

Az Apache Commons Lang 3 másik kulcseleme a NumberUtils osztály.

A várakozásoknak megfelelően az osztály széleskörű hasznossági módszereket kínál, numerikus típusok feldolgozására és manipulálására.

Nézzük meg a összehasonlít () módszer, amely összehasonlítja a különböző primitívek egyenlőségét, mint pl int és hosszú:

@Test public void whenCalledcompareWithIntegers_thenCorrect () {assertThat (NumberUtils.compare (1, 1)) .isEqualTo (0); } @Test public void whenCalledcompareWithLongs_thenCorrect () {assertThat (NumberUtils.compare (1L, 1L)) .isEqualTo (0); }

Ezen felül léteznek a összehasonlít () amelyek működnek byte és rövid, amelyek nagyon hasonlóak a fenti példákhoz.

A következő ebben a felülvizsgálatban a createNumber () és isDigit () mód.

Az első lehetővé teszi számunkra, hogy a húr, míg a második ellenőrzi, hogy a húr csak számjegyekből áll:

@Test public void whenCalledcreateNumber_thenCorrect () {assertThat (NumberUtils.createNumber ("123456")) .isEqualTo (123456); } @Test public void whenCalledisDigits_thenCorrect () {assertThat (NumberUtils.isDigits ("123456")). IsTrue (); } 

Amikor egy szállított tömb mix és max értékeinek megtalálásáról van szó, a NumberUtils osztály erős támogatást nyújt ezekhez a műveletekhez a perc () és max () mód:

@Test public void whenCalledmaxwithIntegerArray_thenCorrect () {int [] tömb = {1, 2, 3, 4, 5, 6}; assertThat (NumberUtils.max (tömb)) .isEqualTo (6); } @Test public void whenCalledminwithIntegerArray_thenCorrect () {int [] tömb = {1, 2, 3, 4, 5, 6}; assertThat (NumberUtils.min (tömb)). isEqualTo (1); } @Test public void whenCalledminwithByteArray_thenCorrect () {byte [] tömb = {1, 2, 3, 4, 5, 6}; assertThat (NumberUtils.min (tömb)) .isEqualTo ((bájt) 1); }

6. A Töredék Osztály

A frakciókkal való munka rendben van, ha tollat ​​és papírdarabot használunk. De át kell-e élnünk ennek a folyamatnak a bonyolultságát, amikor kódot írunk? Nem igazán.

A Töredék osztályban a frakciókat szélben lehet összeadni, kivonni és megszorozni:

@Test public void whenCalledgetFraction_thenCorrect () {assertThat (Fraction.getFraction (5, 6)). IsInstanceOf (Fraction.class); } @Test public void givenTwoFractionInstances_whenCalledadd_thenCorrect () {Fraction frakció1 = Fraction.getFraction (1, 4); 2. tört frakció = Tört frakció (3., 4.); assertThat (tört1.add (tört2) .toString ()). isEqualTo ("1/1"); } @Test public void givenTwoFractionInstances_whenCalledsubstract_thenCorrect () {Fraction frakció1 = Fraction.getFraction (3, 4); Tört frakció2 = Tört frakció (1, 4); assertThat (tört1.subtract (frakció2) .toString ()). isEqualTo ("1/2"); } @Test public void givenTwoFractionInstances_whenCalledmultiply_thenCorrect () {Fraction frakció1 = Fraction.getFraction (3, 4); Tört frakció2 = Tört frakció (1, 4); assertThat (frakció1.multiplyBy (frakció2) .toString ()). isEqualTo ("3/16"); }

Míg a törtekkel végzett műveletek nem minden bizonnyal a leggyakoribb feladatok, amelyekkel napi fejlesztési munkánk során meg kell küzdenünk, a Töredék osztály értékes támogatást nyújt e műveletek egyszerű végrehajtásához.

7. Az SystemUtils Osztály

Néha dinamikus információkat kell beszereznünk az alapul szolgáló Java platform vagy az operációs rendszer különböző tulajdonságairól és változóiról.

Az Apache Commons Lang 3 biztosítja a SystemUtils osztály amiért ezt fájdalommentesen teljesítették.

Vegyük fontolóra például a getJavaHome (), getUserHome () és isJavaVersionAtLeast () mód:

@Test public void whenCalledgetJavaHome_thenCorrect () {assertThat (SystemUtils.getJavaHome ()) .isEqualTo (új fájl ("elérési út / java / jdk")); } @Test public void whenCalledgetUserHome_thenCorrect () {assertThat (SystemUtils.getUserHome ()) .isEqualTo (új fájl ("elérési út / felhasználó / home")); } @Test public void whenCalledisJavaVersionAtLeast_thenCorrect () {assertThat (SystemUtils.isJavaVersionAtLeast (JavaVersion.JAVA_RECENT)). IsTrue (); }

Van néhány további segédprogram, amelyet a SystemUtils osztályos eszközei. Kihagytuk őket, hogy rövidek legyenek a példák.

8. A Lusta inicializáló és készítő osztályok

Az Apache Commons Lang 3 egyik legvonzóbb eleme néhány jól ismert tervezési minta, köztük a lusta inicializálás és az építők mintái.

Tegyük fel például, hogy drágát hoztunk létre Felhasználó osztály (rövidség miatt nem jelenik meg), és el akarjuk halasztani a példányosítást, amíg erre valóban nincs szükség.

Ilyen esetben csak a paraméterezett LazyInitializer absztrakt osztályt kell kibővíteni és felülírni inicializálás () módszer:

public class UserInitializer kiterjeszti a LazyInitializer programot {@Orride protected User Initialize () {return new User ("John", "[email protected]"); }}

Most, ha költséges akarunk lenni Felhasználó objektum, amikor szükséges, csak hívjuk a UserInitializer get () módszer:

@Test public void whenCalledget_thenCorrect () dobja a ConcurrentException {UserInitializer userInitializer = new UserInitializer (); assertThat (userInitializer.get ()). isInstanceOf (Felhasználó.osztály); }

A kap() A metódus a kettős ellenőrzés idiómájának (szálbiztos) megvalósítása egy példánymezőhöz, amint azt a Joshua Bloch „Hatékony Java”, 71. tétel:

privát illékony felhasználói példány; Felhasználó get () {if (instance == null) {synchronized (this) {if (instance == null) instance = new User ("John", "[email protected]"); }}} visszatérési példány; }

Ezenkívül az Apache Commons Lang 3 megvalósítja a HashCodeBuilder osztályt, amely lehetővé teszi számunkra a generálást hash kód() megvalósítások az építőnek különböző paraméterekkel való ellátásával, egy tipikus folyékony API alapján:

@Test public void whenCalledtoHashCode_thenCorrect () {int hashcode = new HashCodeBuilder (17, 37) .append ("John") .append ("[email protected]") .toHashCode (); assertThat (hashcode) .isEqualTo (1269178828); }

Valami hasonlót tehetünk a BasicThreadFactory osztályban, és hozzon létre névadási mintával és prioritással rendelkező démonszálakat:

@Test public void whenCalledBuilder_thenCorrect () {BasicThreadFactory factory = new BasicThreadFactory.Builder () .namingPattern ("workerthread-% d") .daemon (true) .priority (Thread.MAX_PRIORITY) .build (); assertThat (gyár) .isInstanceOf (BasicThreadFactory.class); }

9. Az ConstructorUtils Osztály

A Reflection első osztályú állampolgár az Apache Commons Lang 3-ban.

A könyvtár számos reflexiós osztályt tartalmaz, amely lehetővé teszi számunkra, hogy reflektív módon hozzáférjünk és kezeljük az osztályterületeket és módszereket.

Tegyük fel például, hogy végrehajtottunk egy naiv megoldást Felhasználó domain osztály:

public class Felhasználó {private String name; privát karakterlánc e-mail; // standard konstruktorok / szerelők / beállítók / toString}

Feltételezve, hogy paraméterezett konstruktora az nyilvános, könnyen elérhetjük a ConstructorUtils osztály:

@Test public void whenCalledgetAccessibleConstructor_thenCorrect () {assertThat (ConstructorUtils .getAccessibleConstructor (User.class, String.class, String.class)) .isInstanceOf (Constructor.class); } 

A konstruktőrökön keresztüli standard osztálypéldázás helyett reflektív módon létrehozhatunk Felhasználó példányokat csak felhívva a invokeConstructor () és invokeExactConstructor () mód:

@Test public void, amikor a CallContinvokeConstructor_thenCorrect () kiveti a (z) {assertThat (ConstructorUtils.invokeConstructor (User.class, "név", "email")) .isInstanceOf (User.class) kivételt; } @Test public void, amikorCalledinvokeExactConstructor_thenCorrect () kiveti a (z) {String [] args = {"név", "e-mail"} kivételt; Osztály [] paraméterTípusok = {String.osztály, String.osztály}; assertThat (ConstructorUtils.invokeExactConstructor (User.class, args, parameterTypes)) .isInstanceOf (User.class); } 

10. Az FieldUtils Osztály

Hasonlóképpen, használhatjuk a FieldUtils osztály az osztálymezők reflektív olvasására / írására.

Tegyük fel, hogy szeretnénk egy mezőt kapni a Felhasználó osztály, vagy végül egy mező, amelyet az osztály egy szuperosztálytól örököl.

Ilyen esetben meghívhatjuk a getField () módszer:

@Test public void whenCalledgetField_thenCorrect () {assertThat (FieldUtils.getField (User.class, "név", true) .getName ()) .isEqualTo ("név"); } 

Alternatív megoldásként ha korlátozóbb reflexiós hatókört akarunk használni, és csak a Felhasználó osztályú, és nem szuperosztálytól örökölte, csak a getDeclaredField () módszer:

@Test public void whenCalledgetDeclaredFieldForceAccess_thenCorrect () {assertThat (FieldUtils.getDeclaredField (User.class, "név", true) .getName ()) .isEqualTo ("név"); }

Ezen felül használhatjuk a getAllFields () módszer a visszavert osztály mezõinek lekérésére, és írjon egy értéket egy deklarált mezõbe vagy egy hierarchiában meghatározott mezõbe a writeField () és writeDeclaredField () mód:

@Test public void whenCalledgetAllFields_thenCorrect () {assertThat (FieldUtils.getAllFields (User.class) .length) .isEqualTo (2); } @Test public void, amikor a CalledwriteField_thenCorrect () az IllegalAccessException {FieldUtils.writeField (felhasználó, "név", "Julie", igaz) dobja; assertThat (FieldUtils.readField (felhasználó, "név", igaz)) .isEqualTo ("Julie"); } @Test public void givenFieldUtilsClass_whenCalledwriteDeclaredField_thenCorrect () dobja az IllegalAccessException {FieldUtils.writeDeclaredField (felhasználó, "név", "Julie", igaz); assertThat (FieldUtils.readField (felhasználó, "név", igaz)) .isEqualTo ("Julie"); }

11. Az MethodUtils Osztály

Ugyanezen a vonalon használhatjuk az osztálymódszerek reflexióját a MethodUtils osztály.

Ebben az esetben a Felhasználó osztály' getName () módszer az nyilvános. Tehát elérhetjük a getAccessibleMethod () módszer:

@Test public void whenCalledgetAccessibleMethod_thenCorrect () {assertThat (MethodUtils.getAccessibleMethod (User.class, "getName")) .isInstanceOf (Method.class); } 

Ha reflektív módon hivatkozó módszerekre van szükség, használhatjuk a invokeExactMethod () és invokeMethod () mód:

@Test public void, amikor a CallContinvokeExactMethod_thenCorrect () kivételt dob ​​a {assertThat (MethodUtils.invokeExactMethod (új felhasználó ("John", "[e-mail védett]"), "getName")) .isEqualTo ("John"); } @Test public void, amikorCalledinvokeMethod_thenCorrect () kiveti a (z) {User user = new User ("John", "[email protected]") kivételt; Object method = MethodUtils.invokeMethod (felhasználó, igaz, "setName", "John"); assertThat (user.getName ()). isEqualTo ("John"); }

12. A MutableObject Osztály

Míg a megváltoztathatatlanság a jó objektumorientált szoftver kulcsfontosságú jellemzője, amelyet minden lehetséges esetben alapértelmezésként használnunk kell, sajnos néha változtatható tárgyakkal kell megküzdenünk.

Sőt, a mutálható osztályok létrehozásához sok kazánlap kódra van szükség, amelyet a legtöbb IDE generálhat automatikusan generált beállítókon keresztül.

Ennek érdekében az Apache Commons Lang 3 biztosítja a MutableObject osztály, egy egyszerű burkoló osztály változtatható objektumok létrehozásához minimális felhajtással:

@BeforeClass public static void setUpMutableObject () {mutableObject = new MutableObject ("Kezdeti érték"); } @Test public void whenCalledgetValue_thenCorrect () {assertThat (mutableObject.getValue ()). IsInstanceOf (String.class); } @Test public void whenCalledsetValue_thenCorrect () {mutableObject.setValue ("Egy másik érték"); assertThat (mutableObject.getValue ()). isEqualTo ("Egy másik érték"); } @Test public void whenCalledtoString_thenCorrect () {assertThat (mutableObject.toString ()). IsEqualTo ("Egy másik érték"); } 

Természetesen ez csak egy példa a MutableObject osztály.

Alapszabályként: mindig változatlan osztályok létrehozására kell törekednünk, vagy a legrosszabb esetben is csak a szükséges mutálhatósági szintet kell biztosítani.

13. Az MutablePair Osztály

Elég érdekes, hogy az Apache Commons Lang 3 erős támogatást nyújt a párokhoz, párok és hármasok formájában.

Tehát tegyük fel, hogy létre kell hoznunk egy módosítható rendezett elempárot.

Ilyen esetben a MutablePair osztály:

privát statikus MutablePair mutablePair; @BeforeClass public static void setUpMutablePairInstance () {mutablePair = new MutablePair ("leftElement", "rightElement"); } @Test public void whenCalledgetLeft_thenCorrect () {assertThat (mutablePair.getLeft ()). IsEqualTo ("leftElement"); } @Test public void whenCalledgetRight_thenCorrect () {assertThat (mutablePair.getRight ()). IsEqualTo ("rightElement"); } @Test public void whenCalledsetLeft_thenCorrect () {mutablePair.setLeft ("newLeftElement"); assertThat (mutablePair.getLeft ()). isEqualTo ("newLeftElement"); } 

A legrelevánsabb részlet, amelyet itt érdemes hangsúlyozni, a „tiszta API” osztály.

Lehetővé teszi számunkra, hogy beállítsuk és elérjük a bal és jobb objektumokat, amelyeket a pár be van csomagolva, a szokásos beállítókon keresztül.

14. Az ImmutablePair Osztály

Nem meglepő, hogy létezik a MutablePair osztály, hívják ImmutablePair:

privát statikus ImmutablePair immutablePair = új ImmutablePair ("leftElement", "rightElement"); @Test public void whenCalledgetLeft_thenCorrect () {assertThat (immutablePair.getLeft ()). IsEqualTo ("leftElement"); } @Test public void whenCalledgetRight_thenCorrect () {assertThat (immutablePair.getRight ()). IsEqualTo ("rightElement"); } @Test public void whenCalledof_thenCorrect () {assertThat (ImmutablePair.of ("leftElement", "rightElement")) .isInstanceOf (ImmutablePair.class); } @Test (várható = UnsupportedOperationException.class) public void whenCalledSetValue_thenThrowUnsupportedOperationException () {immutablePair.setValue ("newValue"); } 

Ahogy egy változhatatlan osztálytól elvárhatjuk, minden kísérlet a pár belső állapotának megváltoztatására a érték beállítása() módszer egy an dobását eredményezi UnsupportedOperationException kivétel.

15. A Hármas Osztály

Az utolsó hasznossági osztály, amelyet itt megnézünk, az Hármas.

Mivel az osztály elvont, létrehozhatunk Hármas példányokat a nak,-nek() statikus gyári módszer:

@BeforeClass public static void setUpTripleInstance () {triple = Triple.of ("leftElement", "middleElement", "rightElement"); } @Test public void whenCalledgetLeft_thenCorrect () {assertThat (triple.getLeft ()). IsEqualTo ("leftElement"); } @Test public void whenCalledgetMiddle_thenCorrect () {assertThat (triple.getMiddle ()). IsEqualTo ("middleElement"); } @Test public void whenCalledgetRight_thenCorrect () {assertThat (triple.getRight ()). IsEqualTo ("rightElement"); }

Vannak konkrét megvalósítások mind a mutábilis, mind a megváltoztathatatlan hármasok számára, a MutableTriple és ImmutableTriple osztályok.

Példányaikat paraméterezett konstruktorokon keresztül hozhatjuk létre, nem pedig statikus gyári módszerrel.

Ebben az esetben csak kihagyjuk őket, mivel az API-k nagyon hasonlítanak a MutablePair és ImmutablePair osztályok.

16. Következtetés

Ebben az oktatóanyagban alaposan áttekintettük az Apache Commons Lang 3 által biztosított leghasznosabb segédprogramokat ki a polc .

A könyvtár sok más segédprogramot valósít meg, amelyeket érdemes megnézni. Itt most bemutattuk a leghasznosabbakat, egy eléggé véleményes kritérium alapján.

A teljes könyvtár API-t a hivatalos Javadocs-ban találja.

Szokás szerint az ebben az oktatóanyagban bemutatott összes kódminta elérhető a GitHubon.