Úvod do funkčnej Javy

1. Prehľad

V tomto výučbe poskytneme rýchly prehľad o funkčnej knižnici Java spolu s niekoľkými príkladmi.

2. Funkčná knižnica Java

Knižnica Functional Java je knižnica s otvoreným zdrojom, ktorá slúži na uľahčenie funkčného programovania v prostredí Java. Knižnica poskytuje množstvo základných a pokročilých programovacích abstrakcií, ktoré sa bežne používajú vo funkčnom programovaní.

Veľa funkcií knižnice sa točí okolo F rozhranie. Toto F rozhranie modeluje funkciu, ktorá prijíma vstup typu A a vráti výstup typu B. To všetko je postavené na najlepšom systéme vlastných typov Java.

3. Závislosti Maven

Najprv musíme pridať požadované závislosti do našej pom.xml spis:

 org.funkcnajava funkcna java 4.8.1 org.funkcna java funkcna java 4.8.8 org.funkcna java funkcna java 4.8.1 

4. Definovanie funkcie

Začnime vytvorením funkcie, ktorú môžeme neskôr použiť v našich príkladoch.

Bez funkčnej Javy by základná metóda násobenia vyzerala asi takto:

public static final Integer timesTwoRegular (Integer i) {return i * 2; }

Pomocou funkčnej knižnice Java môžeme túto funkcionalitu definovať trochu elegantnejšie:

verejné statické konečné F timesTwo = i -> i * 2;

Vyššie vidíme príklad F rozhranie, ktoré trvá Celé číslo ako vstup a vráti to Celé číslo krát dva ako jeho výstup.

Tu je ďalší príklad základnej funkcie, ktorá berie znak Celé číslo ako vstup, ale v tomto prípade vráti a Boolovský na označenie, či bol vstup párny alebo nepárny:

verejné statické finále F isEven = i -> i% 2 == 0;

5. Aplikácia funkcie

Teraz, keď máme zavedené naše funkcie, aplikujme ich na množinu údajov.

Knižnica Functional Java poskytuje obvyklú sadu typov na správu údajov, ako sú zoznamy, množiny, polia a mapy. Najdôležitejšie je uvedomiť si, že tieto dátové typy sú nemenné.

Knižnica navyše poskytuje pohodlné funkcie na prevod do a zo štandardných tried zbierok Java V prípade potreby.

V príklade nižšie definujeme zoznam celých čísel a použijeme naše časyDva funkciu. Zavoláme tiež mapa pomocou inline definície tej istej funkcie. Očakávame samozrejme rovnaké výsledky:

public void multiplyNumbers_givenIntList_returnTrue () {List fList = List.list (1, 2, 3, 4); Zoznam fList1 = fList.map (timesTwo); Zoznam fList2 = fList.map (i -> i * 2); assertTrue (fList1.equals (fList2)); }

Ako vidíme mapa vráti zoznam rovnakej veľkosti, kde hodnota každého prvku je hodnotou vstupného zoznamu s použitou funkciou. Samotný zoznam vstupov sa nezmení.

Tu je podobný príklad pomocou nášho isEven funkcia:

public void spočítaťEvenNumbers_givenIntList_returnTrue () {List fList = List.list (3, 4, 5, 6); Zoznam evenList = fList.map (isEven); List evenListTrueResult = List.list (false, true, false, true); assertTrue (evenList.equals (evenListTrueResult)); }

Keďže mapa metóda vráti zoznam, môžeme na jej výstup použiť inú funkciu. Poradie, v akom sa dovolávame našich mapa funkcie menia náš výsledný výstup:

public void applyMultipleFunctions_givenIntList_returnFalse () {List fList = List.list (1, 2, 3, 4); Zoznam fList1 = fList.map (timesTwo) .map (plusOne); Zoznam fList2 = fList.map (plusOne) .map (timesTwo); assertFalse (fList1.equals (fList2)); }

Výstup z vyššie uvedených zoznamov bude:

Zoznam (3,5,7,9) Zoznam (4,6,8,10)

6. Filtrovanie pomocou funkcie

Ďalšou často používanou operáciou vo funkčnom programovaní je prijať vstup a odfiltrovať údaje na základe niektorých kritérií. A ako ste už pravdepodobne uhádli, tieto filtračné kritériá sú poskytované vo forme funkcie. Táto funkcia bude musieť vrátiť boolean, aby označila, či je potrebné do výstupu zahrnúť údaje.

Teraz použijeme našu isEven funkcia na filtrovanie nepárnych čísel zo vstupného poľa pomocou filter metóda:

public void filterList_givenIntList_returnResult () {Array pole = Array.array (3, 4, 5, 6); ArrayfiltrovaneArray = array.filter (isEven); Výsledok poľa = Array.array (4, 6); assertTrue (filterArray.equals (výsledok)); }

Jedným zaujímavým postrehom je, že v tomto príklade sme použili znak Pole namiesto a Zoznam ako sme použili v predchádzajúcich príkladoch, a naša funkcia fungovala dobre. Kvôli spôsobu, akým sú funkcie abstrahované a vykonávané, si nemusia uvedomovať, aká metóda bola použitá na zhromaždenie vstupu a výstupu.

V tomto príklade sme použili aj náš vlastný isEven funkčná, ale funkčná Java vlastná Celé číslo trieda má tiež štandardné funkcie pre základné číselné porovnania.

7. Aplikácia logickej logiky pomocou funkcie

Vo funkčnom programovaní často používame logiku ako „robte to iba vtedy, ak všetky prvky vyhovujú niektorej podmienke“ alebo „robte to, iba ak aspoň jeden prvok spĺňa určitú podmienku“.

Knižnica Functional Java nám poskytuje skratky pre túto logiku prostredníctvom servera existuje a pre všetkých metódy:

public void checkForLowerCase_givenStringArray_returnResult () {Array array = Array.array ("Vitajte", "Komu", "baeldung"); assertTrue (array.exists (s -> List.fromString (s) .forall (Characters.isLowerCase))); Array array2 = Array.array ("Vitajte", "Komu", "Baeldung"); assertFalse (array2.exists (s -> List.fromString (s) .forall (Characters.isLowerCase))); assertFalse (array.forall (s -> List.fromString (s) .forall (Characters.isLowerCase))); }

Vo vyššie uvedenom príklade sme ako vstup použili pole reťazcov. Volá sa fromString funkcia prevedie každý z reťazcov z poľa na zoznam znakov. Na každý z týchto zoznamov sme sa prihlásili navždy (Characters.isLowerCase).

Ako ste pravdepodobne uhádli, Characters.isLowerCase je funkcia, ktorá vracia true, ak sú znaky malé. Takže žiadosť navždy (Characters.isLowerCase) na zoznam znakov sa iba vráti pravda ak sa celý zoznam skladá z malých písmen, čo potom znamená, že pôvodný reťazec bol malými písmenami.

V prvých dvoch testoch sme použili existuje pretože sme chceli iba vedieť, či je aspoň v jednom reťazci malé písmeno. Tretí použitý test pre všetkých na overenie, či sú všetky reťazce malé.

8. Zaobchádzanie s voliteľnými hodnotami pomocou funkcie

Spracovanie voliteľných hodnôt v kóde zvyčajne vyžaduje == null alebo isNotBlank kontroly. Java 8 teraz poskytuje Voliteľné triedy, aby tieto kontroly zvládla elegantnejšie, a funkčná knižnica Java ponúka podobnú konštrukciu na elegantné riešenie chýbajúcich údajov prostredníctvom svojej triedy Option:

public void checkOptions_givenOptions_returnResult () {Option n1 = Option.some (1); Možnosť n2 = Možnosť.some (2); Možnosť n3 = Možnosť.none (); F function = i -> i% 2 == 0? Option.some (i + 100): Option.none (); Možnosť výsledok1 = n1.bind (funkcia); Možnosť výsledok2 = n2.bind (funkcia); Možnosť výsledok3 = n3.bind (funkcia); assertEquals (Option.none (), result1); assertEquals (Option.some (102), result2); assertEquals (Option.none (), result3); }

9. Redukcia množiny pomocou funkcie

Na záver sa pozrieme na funkčnosť na zmenšenie množiny. „Redukcia množiny“ je efektný spôsob, ako povedať „zrolovať ich do jednej hodnoty“.

Knižnica Functional Java označuje túto funkcionalitu ako skladanie.

Je potrebné uviesť funkciu, ktorá označuje, čo znamená zložiť prvok. Príkladom toho je Celé čísla.prid je potrebné pridať funkciu na zobrazenie celých čísel v poli alebo zozname.

Na základe toho, čo funkcia robí pri skladaní, sa výsledok môže líšiť podľa toho, či začnete skladať sprava alebo zľava. Preto funkčná knižnica Java poskytuje obe verzie:

public void foldLeft_givenArray_returnResult () {Array intArray = Array.array (17, 44, 67, 2, 22, 80, 1, 27); int sumAll = intArray.foldLeft (Integers.add, 0); assertEquals (260, sumAll); int sumEven = intArray.filter (isEven) .foldLeft (Integers.add, 0); assertEquals (148, sumEven); }

Prvý foldLeft jednoducho pridá všetky celé čísla. Zatiaľ čo druhý najskôr použije filter a potom pridá zvyšné celé čísla.

10. Záver

Tento článok je iba krátkym úvodom do funkčnej knižnice Java.

Celý zdrojový kód článku je ako vždy k dispozícii na GitHub.


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