Úvod do služby jOOL

1. Prehľad

V tomto článku sa pozrieme na jOOLknižnica - ďalší produkt z jOOQ.

2. Závislosť od Maven

Začnime tým, že do vašej pridáme závislosť Maven pom.xml:

 org.jooq jool 0.9.12 

Najnovšiu verziu nájdete tu.

3. Funkčné rozhrania

V prostredí Java 8 sú funkčné rozhrania dosť obmedzené. Prijímajú maximálny počet dvoch parametrov a nemajú veľa ďalších funkcií.

jOOL to opravuje preukázaním súboru nových funkčných rozhraní, ktoré dokážu prijať aj 16 parametrov (z Funkcia1 Funkcia16) a sú obohatené o ďalšie užitočné metódy.

Napríklad na vytvorenie funkcie, ktorá má tri argumenty, môžeme použiť Funkcia 3:

Funkcia3 dĺžkaSum = (v1, v2, v3) -> v1.length () + v2.length () + v3.length ();

V čistej Jave by ste si to museli implementovať sami. Okrem toho majú funkčné rozhrania z jOOL svoju metódu applyPartially () ktorý nám umožňuje ľahko vykonať čiastočnú aplikáciu:

Funkcia2 addTwoNumbers = (v1, v2) -> v1 + v2; Function1 addToTwo = addTwoNumbers.applyPartially (2); Výsledok celého čísla = addToTwo.apply (5); assertEquals (result, (Integer) 7);

Keď máme metódu, ktorá je z a Funkcia2 typu, môžeme ho ľahko transformovať na štandardnú Javu BiFunkcia použitím a toBiFunction () metóda:

BiFunction biFunc = addTwoNumbers.toBiFunction ();

Podobne existuje a k funkcii() metóda v Funkcia1 typu.

4. Tice

N-tica je vo svete funkčného programovania veľmi dôležitá konštrukcia. Je to písaný kontajner pre hodnoty, kde každá hodnota môže mať iný typ. N-tice sa často používajú ako argumenty funkcií.

Sú tiež veľmi užitočné pri transformácii na prúd udalostí. V službe jOOL máme n-tice, ktoré môžu obsahovať jednu až šestnásť hodnôt poskytnutých Tuple1 Tuple16 typy:

n-tica (2, 2)

A pre štyri hodnoty:

n-tica (1,2,3,4); 

Uvažujme príklad, keď máme postupnosť n-tíc, ktorá niesla 3 hodnoty:

Sekv personDetails = Seq.of (n-tica ("michael", "podobný", 49), n-tica ("jodie", "premenná", 43)); Tuple2 tuple = n-tica („zima“, „leto“); Zoznam result = personDetails .map (t -> t.limit2 (). concat (n-tice)). toList (); assertEquals (result, Arrays.asList (n-tice ("michael", "podobne", "zima", "leto"), n-tice ("jodie", "premenna", "zima", "leto")));

Na n-tice môžeme použiť rôzne druhy transformácií. Najprv nazývame a limit2 () metóda vziať iba dve hodnoty z Tuple3. Potom voláme a concat () metóda na zreťazenie dvoch n-tíc.

Vo výsledku dostaneme hodnoty, ktoré sú a Tuple4 typu.

5. Sekv

The Sekv konštrukt pridáva metódy vyššej úrovne na a Prúd zatiaľ čo často používa svoje metódy pod ním.

5.1. Obsahuje operácie

Nájdeme niekoľko variantov metód kontrolujúcich prítomnosť prvkov v a Sekv. Niektoré z týchto metód používajú anyMatch () metóda z a Prúd trieda:

assertTrue (Seq.of (1, 2, 3, 4). obsahuje (2)); assertTrue (Seq.of (1, 2, 3, 4). obsahuje All (2, 3)); assertTrue (Seq.of (1, 2, 3, 4). obsahuje Any (2, 5)); 

5.2. Pripojte sa k prevádzke

Keď máme dva streamy a chceme sa k nim pripojiť (podobne ako pri operácii spojenia SQL s dvoma súbormi údajov), pomocou štandardného Prúd triedy nie je veľmi elegantný spôsob, ako to dosiahnuť:

Stream vľavo = Stream.of (1, 2, 4); Stream vpravo = Stream.of (1, 2, 3); Zoznam rightCollected = right.collect (Collectors.toList ()); Zoznam collect = ľavý .filter (rightCollected :: contains) .collect (Collectors.toList ()); assertEquals (collect, Arrays.asList (1, 2));

Musíme pozbierať správny stream do zoznamu, aby sa zabránilo java.lang.IllegalStateException: stream už bol prevádzkovaný alebo uzavretý. Ďalej musíme vykonať operáciu vedľajšieho účinku prístupom k a vpravoZbierané zoznam z a filter metóda. Je to náchylné na chyby a nie je to elegantný spôsob spojenia dvoch súborov údajov.

NašťastieSekv má užitočné metódy na vnútorné, ľavé a pravé spojenie súborov údajov. Tieto metódy skrývajú jeho implementáciu a odhaľujú elegantné API.

Vnútorné spojenie môžeme urobiť pomocou znaku innerJoin () metóda:

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

Podľa toho môžeme urobiť pravé a ľavé spojenie:

assertEquals (Seq.of (1, 2, 4) .leftOuterJoin (Seq.of (1, 2, 3), (a, b) -> a == b) .toList (), Arrays.asList (n-tica (1 , 1), n-tica (2, 2), n-tica (4, nulová))); assertEquals (Seq.of (1, 2, 4) .rightOuterJoin (Seq.of (1, 2, 3), (a, b) -> a == b) .toList (), Arrays.asList (n-tica (1 , 1), n-tica (2, 2), n-tica (nulová, 3)));

Existuje dokonca aj crossJoin () metóda umožňujúca kartézske spojenie dvoch súborov údajov:

assertEquals (Seq.of (1, 2) .crossJoin (Seq.of ("A", "B")). toList (), Arrays.asList (n-tice (1, "A"), n-tice (1, "B "), n-tica (2," A "), n-tica (2," B ")));

5.3. Manipulácia a Sekv

Sekv má mnoho užitočných metód na manipuláciu so sekvenciami prvkov. Pozrime sa na niektoré z nich.

Môžeme použiť a cyklus () metóda na opakované prevzatie prvkov zo zdrojovej sekvencie. Vytvorí nekonečný prúd, takže pri zhromažďovaní výsledkov do zoznamu musíme byť opatrní, a preto musíme použiť a limit () metóda na transformáciu nekonečnej sekvencie na konečnú:

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

Povedzme, že chceme duplikovať všetky prvky z jednej postupnosti do druhej postupnosti. The duplikát () metóda robí presne toto:

assertEquals (Seq.of (1, 2, 3) .duplicate (). map ((first, second) -> tuple (first.toList (), second.toList ())), n-tice (Arrays.asList (1, 2, 3), Arrays.asList (1, 2, 3))); 

Vracajúci sa typ a duplikát () metóda je n-tica dvoch sekvencií.

Povedzme, že máme postupnosť celých čísel a chceme ju pomocou nejakého predikátu rozdeliť na dve postupnosti. Môžeme použiť a oddiel () metóda:

assertEquals (Seq.of (1, 2, 3, 4). partition (i -> i> 2) .map ((first, second) -> tuple (first.toList (), second.toList ())), n-tica (Arrays.asList (3, 4), Arrays.asList (1, 2)));

5.4. Zoskupovanie prvkov

Zoskupenie prvkov podľa kľúča pomocou Prúd API je ťažkopádne a neintuitívne - pretože ho musíme používať zbierať () metóda s a Collectors.groupingBy zberateľ.

Sekv skryje tento kód za a groupBy () metóda, ktorá sa vráti Mapa takže nie je potrebné používať a zbierať () metóda výslovne:

Mapa expectAfterGroupBy = new HashMap (); expectAfterGroupBy.put (1, Arrays.asList (1, 3)); expectAfterGroupBy.put (0, Arrays.asList (2, 4)); assertEquals (Seq.of (1, 2, 3, 4) .groupBy (i -> i% 2), expectAfterGroupBy);

5.5. Preskakujúce prvky

Povedzme, že máme postupnosť prvkov a chceme preskočiť prvky, zatiaľ čo predikát sa nezhoduje. Keď je predikát splnený, prvky by mali pristáť vo výslednej postupnosti.

Môžeme použiť a skipWhile () metóda na to:

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

Rovnaký výsledok môžeme dosiahnuť pomocou a skipUntil () metóda:

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

5.6. Sekvencie na zips

Keď spracovávame sekvencie prvkov, často je potrebné ich skomprimovať do jednej sekvencie.

The PSČ() API, ktoré sa dá použiť na spojenie dvoch sekvencií do jednej:

assertEquals (Seq.of (1, 2, 3) .zip (Seq.of ("a", "b", "c")). toList (), Arrays.asList (n-tice (1, "a"), n-tica (2, "b"), n-tica (3, "c")));

Výsledná sekvencia obsahuje n-tice dvoch prvkov.

Keď skomprimujeme dve sekvencie, ale chceme ich skomprimovať konkrétnym spôsobom, môžeme zložiť a BiFunkcia do a PSČ() metóda, ktorá definuje spôsob zipovania prvkov:

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"));

Niekedy je užitočné skomprimovať postupnosť pomocou indexu prvkov v tejto sekvencii pomocou indexu zipWithIndex () API:

assertEquals (Seq.of ("a", "b", "c"). zipWithIndex (). toList (), Arrays.asList (tuple ("a", 0L), n-tice ("b", 1L), n-tice ("c", 2L)));

6. Konverzia zaškrtnutých výnimiek na nezačiarknuté

Povedzme, že máme metódu, ktorá vezme reťazec a môže vyvolať kontrolovanú výnimku:

public Integer methodThatThrowsChecked (String arg) hodí Exception {return arg.length (); }

Potom chceme mapovať prvky a Prúd uplatnenie tejto metódy na každý prvok. Neexistuje spôsob, ako zvládnuť túto výnimku vyššie, takže túto výnimku musíme spracovať v a mapa () metóda:

List collect = Stream.of ("a", "b", "c"). Map (elem -> {try {return methodThatThrowsChecked (elem);} catch (Exception e) {e.printStackTrace (); throw new RuntimeException (e);}}). collect (Collectors.toList ()); assertEquals (collect, Arrays.asList (1, 1, 1));

S touto výnimkou toho veľa nemôžeme urobiť kvôli návrhu funkčných rozhraní v Jave, takže v klauzule catch prevádzame skontrolovanú výnimku na nekontrolovanú.

Našťastie v JOOL existuje Nezačiarknuté trieda, ktorá má metódy, ktoré môžu prevádzať skontrolované výnimky na nekontrolované výnimky:

Zoznam collect = Stream.of ("a", "b", "c") .map (Unchecked.function (elem -> methodThatThrowsChecked (elem))) .collect (Collectors.toList ()); assertEquals (collect, Arrays.asList (1, 1, 1));

Zalamujeme hovor na a methodThatThrowsChecked () do Unchecked.function () metóda, ktorá sa stará o prevod výnimiek.

7. Záver

Tento článok ukazuje, ako používať knižnicu jOOL, ktorá pridáva ďalšie užitočné metódy k štandardu Java Prúd API.

Implementáciu všetkých týchto príkladov a útržkov kódu nájdete v projekte GitHub - jedná sa o projekt Maven, takže by malo byť ľahké ho importovať a spustiť tak, ako je.


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