A jOOL bemutatása

1. Áttekintés

Ebben a cikkben a jOOL-t fogjuk megvizsgálnikönyvtár - a jOOQ másik terméke.

2. Maven-függőség

Kezdjük azzal, hogy hozzáadunk egy Maven-függőséget pom.xml:

 org.jooq jool 0.9.12 

A legújabb verziót itt találja.

3. Funkcionális interfészek

A Java 8-ban a funkcionális interfészek meglehetősen korlátozottak. Elfogadják a két paraméter maximális számát, és nincs sok további funkciójuk.

A jOOL kijavítja, hogy bizonyít egy olyan új funkcionális interfészt, amely akár 16 paramétert is képes elfogadni ( Funkció1 akár Funkció16) és további hasznos módszerekkel gazdagodnak.

Például egy olyan függvény létrehozásához, amely három argumentumot tartalmaz, használhatjuk 3. funkció:

Funkció3 lengthSum = (v1, v2, v3) -> v1.length () + v2.length () + v3.length ();

A tiszta Java-ban egyedül kell végrehajtania. Emellett a jOOL funkcionális interfészeinek van egy módszere ApplyPartially () amely lehetővé teszi számunkra a részleges alkalmazás egyszerű végrehajtását:

2. függvény addTwoNumbers = (v1, v2) -> v1 + v2; Function1 addToTwo = addTwoNumbers.applyPartially (2); Egész eredmény = addToTwo.apply (5); assertEquals (eredmény, (Egész) 7);

Amikor van egy módszerünk, amely a Funkció2 típusú, könnyen átalakíthatjuk standard Java-vá BiFunction az a használatával toBiFunction () módszer:

BiFunction biFunc = addTwoNumbers.toBiFunction ();

Hasonlóképpen van egy funkcionálni, működtetni() módszer ben Funkció1 típus.

4. Tollok

A tuple nagyon fontos konstrukció a funkcionális programozási világban. Ez egy tipizált konténer azokhoz az értékekhez, ahol az egyes értékeknek más típusú lehet. A sorrendeket gyakran használják függvény argumentumként.

Nagyon hasznosak akkor is, amikor átalakulásokat hajtanak végre egy eseményfolyamon. A jOOL-ban vannak olyan sorrendjeink, amelyek egy vagy tizenhat értéket tartalmazhatnak, az általuk biztosított Tuple1 akár Tuple16 típusok:

kettő (2, 2)

És négy értékre:

kettő (1,2,3,4); 

Vegyünk egy példát, ha van egy sor sorrendünk, amely 3 értéket tartalmaz:

Szekvencia personDetails = Szekvencia (tuple ("michael", "hasonló", 49), tuple ("jodie", "változó", 43)); Tuple2 tuple = tuple ("tél", "nyár"); Lista eredmény = személyRészletek .térkép (t -> t.limit2 (). concat (kettő)). toList (); assertEquals (eredmény, Arrays.asList (tuple ("michael", "hasonló", "tél", "nyár"), tuple ("jodie", "változó", "tél", "nyár"));

Különböző típusú transzformációkat használhatunk a sorrendben. Először hívjuk a limit2 () módszer, amelyből csak két értéket vehet fel Tuple3. Akkor hívjuk a concat () módszer két tömb összefűzésére.

Ennek eredményeként olyan értékeket kapunk, amelyek a Tuple4 típus.

5. Szekvencia

A Szekvencia A construct magasabb szintű módszereket ad hozzá a Folyam miközben gyakran alatta használja a módszereit.

5.1. Műveleteket tartalmaz

Találhatunk néhány módszert az elemek jelenlétének ellenőrzésére az a-ban Szekvencia Ezen módszerek egy része az anyMatch () módszer a Folyam osztály:

assertTrue ((1, 2, 3, 4). tartalmazza (2)); assertTrue (Az (1, 2, 3, 4) szekvencia. Mindent tartalmaz (2, 3)); assertTrue (Az (1, 2, 3, 4) szekvencia. tartalmaz Bármely (2, 5)); 

5.2. Csatlakozás műveletekhez

Ha két adatfolyamunk van, és csatlakozni akarunk hozzájuk (hasonlóan két adatkészlet SQL-összekapcsolási műveletéhez), egy szabvány használatával Folyam osztály nem túl elegáns módszer erre:

Stream left = Stream.of (1, 2, 4); Stream jobb = Stream.of (1, 2, 3); List rightCollected = right.collect (Collectors.toList ()); Lista gyűjt = balra .szűrő (rightCollected :: tartalmaz) .collect (Collectors.toList ()); assertEquals (gyűjt, Arrays.asList (1, 2));

Gyűjtenünk kell jobb stream egy listára, hogy megakadályozza java.lang.IllegalStateException: az adatfolyamot már működtették vagy bezárták. Ezután mellékhatás-műveletet kell végrehajtanunk az a elérésével rightCollected lista a szűrő módszer. Hibára hajlamos és nem elegáns módszer két adatkészlet összekapcsolására.

Szerencsére,Szekvencia hasznos módszerekkel rendelkezik az adatkészletek belső, bal és jobb összekapcsolására. Ezek a módszerek elrejtik annak megvalósítását, amely elegáns API-t tesz ki.

Belső csatlakozást tehetünk egy an használatával belső összekapcsolás() módszer:

assertEquals (Seq.of (1, 2, 4) .innerJoin (Seq.of (1, 2, 3), (a, b) -> a == b) .toList (), Arrays.asList (tuple (1 (1), kettő (2, 2)));

Ennek megfelelően tehetünk jobb és bal csatlakozást:

assertEquals (Seq.of (1, 2, 4) .leftOuterJoin (Seq.of (1, 2, 3), (a, b) -> a == b) .toList (), Arrays.asList (tuple (1 , 1), duplán (2, 2), duplán (4, null))); assertEquals (Seq.of (1, 2, 4) .rightOuterJoin (Seq.of (1, 2, 3), (a, b) -> a == b) .toList (), Arrays.asList (tuple (1 , 1), két (2, 2), két (null, 3)));

Van még egy crossJoin () módszer, amely lehetővé teszi két adatkészlet derékszögű összekapcsolását:

assertEquals (Seq.of (1, 2) .crossJoin (Seq.of ("A", "B")). toList (), Arrays.asList (tuple (1, "A"), tuple (1, "B) "), tuple (2," A "), tuple (2," B ")));

5.3. Manipulálás a Szekvencia

Szekvencia számos hasznos módszerrel rendelkezik az elemek sorozatainak manipulálására. Nézzünk meg néhányat közülük.

Használhatjuk a ciklus() módszer, hogy többször is vegyen elemeket egy forrássorból. Végtelen folyamot hoz létre, ezért körültekintőnek kell lennünk, amikor az eredményeket listára gyűjtjük, így a határ() módszer a végtelen szekvencia végessé alakítására:

assertEquals (Seq.of (1, 2, 3) .cycle (). limit (9) .toList (), Arrays.asList (1, 2, 3, 1, 2, 3, 1, 2, 3));

Tegyük fel, hogy az összes elemet meg akarjuk másolni egy sorozatból a második sorozatba. A másolat() módszer pontosan ezt teszi:

assertEquals (Seq.of (1, 2, 3) .duplicate (). map ((first, second) -> tuple (first.toList (), second.toList ())), tuple (Arrays.asList (1, 2, 3), tömbök. AsList (1, 2, 3))); 

Visszatérő típusú a másolat() A módszer két szekvencia duplája.

Tegyük fel, hogy egész számokból álló szekvenciánk van, és ezt a szekvenciát két predikátum segítségével két szekvenciára szeretnénk osztani. Használhatjuk a partíció () módszer:

assertEquals (1., 2., 3., 4. szekvencia. partíció (i -> i> 2). térkép ((első, második) -> duplán (első.lista (), második.lista ())), tuple (Tömbök.asList (3, 4), Tömbök.ASList (1, 2)));

5.4. Elemek csoportosítása

Az elemek csoportosítása egy kulcs segítségével a Folyam Az API nehézkes és nem intuitív - mert használnunk kell gyűjt() módszer a Gyűjtők.csoportosításBy gyűjtő.

Szekvencia elrejti ezt a kódot a mögött csoportosít() visszatérő módszer Térkép így nincs szükség az a használatára gyűjt() módszer kifejezetten:

Térkép VárhatóAfterGroupBy = új HashMap (); VárhatóAfterGroupBy.put (1, Arrays.asList (1, 3)); VárhatóAfterGroupBy.put (0, Arrays.asList (2, 4)); assertEquals (1., 2., 3., 4. szekvencia) .groupBy (i -> i% 2), várhatóAfterGroupBy);

5.5. Az elemek kihagyása

Tegyük fel, hogy van egy elemsorozatunk, és ki akarjuk hagyni az elemeket, miközben az állítmány nincs egyeztetve. Ha egy állítmány teljesül, akkor az elemeknek egy ebből következő sorrendben kell landolniuk.

Használhatjuk a skipWhile () módszer erre:

assertEquals ((1, 2, 3, 4, 5) .skipWhile (i -> i <3) .toList (), Arrays.asList (3, 4, 5));

Ugyanezt az eredményt érhetjük el az a használatával skipUntil () módszer:

assertEquals ((1, 2, 3, 4, 5) .skipUntil (i -> i == 3) .toList (), Arrays.asList (3, 4, 5));

5.6. Zippzósorozatok

Amikor elemsorozatot dolgozunk fel, gyakran szükség van egy sorozatba tömöríteni őket.

A postai irányítószám() API, amellyel két szekvenciát egybe lehet tömöríteni:

assertEquals (Seq.of (1, 2, 3) .zip (Seq.of ("a", "b", "c")). toList (), Arrays.asList (tuple (1, "a"), tuple (2, "b"), tuple (3, "c")));

Az eredményül kapott szekvencia két elemből áll.

Amikor két szekvenciát tömörítünk, de azokat egy meghatározott módon szeretnénk tömöríteni, akkor átadhatjuk a BiFunction a postai irányítószám() módszer, amely meghatározza az elemek tömörítésének módját:

assertEquals (Seq.of (1, 2, 3) .zip (Seq.of ("a", "b", "c"), (x, y) -> x + ":" + y) .toList ( ), Arrays.asList ("1: a", "2: b", "3: c"));

Előfordul, hogy hasznos a sorozat szinkronizálása az ebben a szekvenciában található elemek indexével, a zipWithIndex () API:

assertEquals (Seq.of ("a", "b", "c"). zipWithIndex (). toList (), tömbök ("c", 2L)));

6. Az ellenőrzött kivételek konvertálása nem ellenőrzöttekké

Tegyük fel, hogy van egy módszerünk, amely egy karakterláncot vesz fel, és be tudja dobni az ellenőrzött kivételt:

public Integer methodThatThrowsChecked (string arg) dobja a Kivételt {return arg.length (); }

Ezután szeretnénk feltérképezni a Folyam alkalmazva azt a módszert az egyes elemekre. Ezt a kivételt nem lehet magasabb szinten kezelni, ezért ezt a kivételt az a-ban kell kezelnünk térkép() módszer:

List collect = Stream.of ("a", "b", "c"). Map (elem -> {try {return methodThatThrowsChecked (elem);} catch (e kivétel) {e.printStackTrace (); dobjon új RuntimeException (e);}}). gyűjt (Collectors.toList ()); assertEquals (gyűjt, tömbök.asList (1, 1, 1));

Ezzel a kivétellel nem sokat tehetünk a Java funkcionális interfészeinek kialakítása miatt, ezért egy fogási záradékban egy bejelölt kivételt ellenőrizetlenné alakítunk.

Szerencsére egy jOOL-ban van egy Ellenőrizetlen osztály, amelynek vannak olyan módszerei, amelyek átalakíthatják a bejelölt kivételeket nem ellenőrzött kivételekké:

Lista gyűjt = Stream.of ("a", "b", "c") .map (Nem ellenőrzött funkció (elem -> methodThatThrowsChecked (elem))) .collect (Collectors.toList ()); assertEquals (gyűjt, tömbök.asList (1, 1, 1));

Hívást intézünk a methodThatThrowsChecked () egy an Unchecked.function () módszer, amely kezeli az alatta lévő kivételek konvertálását.

7. Következtetés

Ez a cikk bemutatja a jOOL könyvtár használatát, amely hasznos kiegészítő módszereket ad hozzá a Java szabványhoz Folyam API.

Ezeknek a példáknak és kódrészleteknek a megvalósítása megtalálható a GitHub projektben - ez egy Maven projekt, ezért könnyen importálhatónak és futtathatónak kell lennie.