Inleiding tot functionele Java

1. Overzicht

In deze tutorial geven we een kort overzicht van de functionele Java-bibliotheek samen met een paar voorbeelden.

2. De functionele Java-bibliotheek

De functionele Java-bibliotheek is een open source-bibliotheek die bedoeld is om functioneel programmeren in Java te vergemakkelijken. De bibliotheek biedt veel basis- en geavanceerde abstracties van programmeren die vaak worden gebruikt bij functioneel programmeren.

Veel van de functionaliteit van de bibliotheek draait om de F. koppel. Dit F. interface modelleert een functie die een invoer van het type nodig heeft EEN en retourneert een uitvoer van het type B. Dit alles is gebouwd bovenop Java's eigen type systeem.

3. Maven afhankelijkheden

Eerst moeten we de vereiste afhankelijkheden toevoegen aan onze pom.xml het dossier:

 org.functionaljava functionaljava 4.8.1 org.functionaljava functionaljava-java8 4.8.1 org.functionaljava functionaljava-quickcheck 4.8.1 org.functionaljava functioneeljava-java-core 4.8.1 

4. Een functie definiëren

Laten we beginnen met het maken van een functie die we later in onze voorbeelden kunnen gebruiken.

Zonder functionele Java zou een eenvoudige vermenigvuldigingsmethode er ongeveer zo uitzien:

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

Met behulp van de functionele Java-bibliotheek kunnen we deze functionaliteit iets eleganter definiëren:

openbare statische laatste F keerTwee = i -> i * 2;

Hierboven zien we een voorbeeld van de F. interface die een Geheel getal als invoer en geeft dat terug Geheel getal maal twee als output.

Hier is nog een voorbeeld van een basisfunctie waaraan een Geheel getal als invoer, maar retourneert in dit geval een Boolean om aan te geven of de invoer even of oneven was:

openbare statische finale F isEven = i -> i% 2 == 0;

5. Een functie toepassen

Nu we onze functies hebben, gaan we ze toepassen op een dataset.

De functionele Java-bibliotheek biedt de gebruikelijke set typen voor het beheren van gegevens zoals lijsten, sets, arrays en kaarten. Het belangrijkste om te beseffen is dat deze gegevenstypen onveranderlijk zijn.

Bovendien biedt de bibliotheek gemaksfuncties om van en naar standaard Java Collections-klassen te converteren indien nodig.

In het onderstaande voorbeeld zullen we een lijst met gehele getallen definiëren en onze toepassen keer Twee functie eraan. We zullen ook bellen kaart met behulp van een inline definitie van dezelfde functie. We verwachten natuurlijk dat de resultaten hetzelfde zijn:

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

Zoals we kunnen zien kaart geeft een lijst van dezelfde grootte terug, waarbij de waarde van elk element de waarde is van de invoerlijst waarop de functie is toegepast. De invoerlijst zelf verandert niet.

Hier is een soortgelijk voorbeeld met onze isZelfs functie:

openbare leegte berekenEvenNumbers_givenIntList_returnTrue () {List fList = List.list (3, 4, 5, 6); Lijst evenList = fList.map (isEven); Lijst evenListTrueResult = List.list (false, true, false, true); assertTrue (evenList.equals (evenListTrueResult)); }

Sinds de kaart methode retourneert een lijst, we kunnen een andere functie toepassen op zijn uitvoer. De volgorde waarin we onze kaart functies verandert onze resulterende output:

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

De output van de bovenstaande lijsten zal zijn:

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

6. Filteren met een functie

Een andere veelgebruikte bewerking bij Functioneel Programmeren is om neem een ​​input en filter gegevens uit op basis van enkele criteria. En zoals je waarschijnlijk al geraden hebt, worden deze filtercriteria geleverd in de vorm van een functie. Deze functie moet een booleaanse waarde retourneren om aan te geven of de gegevens al dan niet in de uitvoer moeten worden opgenomen.

Laten we nu onze isZelfs functie om de oneven getallen uit een invoerarray te filteren met de filter methode:

openbare ongeldige filterList_givenIntList_returnResult () {Array array = Array.array (3, 4, 5, 6); Array filterArray = array.filter (isEven); Array-resultaat = Array.array (4, 6); assertTrue (filterArray.equals (resultaat)); }

Een interessante observatie is dat we in dit voorbeeld een Array inplaats van een Lijst zoals we in eerdere voorbeelden hebben gebruikt, en onze functie werkte prima. Vanwege de manier waarop functies worden geabstraheerd en uitgevoerd, hoeven ze niet te weten welke methode is gebruikt om de invoer en uitvoer te verzamelen.

In dit voorbeeld hebben we ook onze eigen gebruikt isZelfs functie, maar Functioneel Java's eigen Geheel getal class heeft ook standaardfuncties voor numerieke basisvergelijkingen.

7. Booleaanse logica toepassen met een functie

Bij Functioneel Programmeren gebruiken we vaak logica zoals "doe dit alleen als alle elementen aan een bepaalde voorwaarde voldoen", of "doe dit alleen als tenminste één element aan een bepaalde voorwaarde voldoet".

De functionele Java-bibliotheek biedt ons snelkoppelingen voor deze logica via de bestaat en de voor iedereen methoden:

openbare ongeldigheid checkForLowerCase_givenStringArray_returnResult () {Array array = Array.array ("Welkom", "Aan", "baeldung"); assertTrue (array.exists (s -> List.fromString (s) .forall (Characters.isLowerCase))); Array array2 = Array.array ("Welkom", "Bij", "Baeldung"); assertFalse (array2.exists (s -> List.fromString (s) .forall (Characters.isLowerCase))); assertFalse (array.forall (s -> List.fromString (s) .forall (Characters.isLowerCase))); }

In het bovenstaande voorbeeld hebben we een reeks strings gebruikt als onze invoer. Bellen met het fromString functie zal elk van de strings uit de array naar een lijst met karakters converteren. Op elk van die lijsten hebben we ons toegepast forall (Characters.isLowerCase).

Zoals je waarschijnlijk al geraden had, Characters.isLowerCase is een functie die true retourneert als een teken in kleine letters is. Dus solliciteren forall (Characters.isLowerCase) naar een lijst met karakters zal alleen terugkeren waar als de hele lijst uit kleine letters bestaat, wat op zijn beurt aangeeft dat de originele string allemaal kleine letters was.

In de eerste twee tests gebruikten we bestaat omdat we alleen wilden weten of ten minste één tekenreeks kleine letters was. De derde gebruikte test voor iedereen om te controleren of alle tekenreeksen kleine letters waren.

8. Omgaan met optionele waarden met een functie

Het afhandelen van optionele waarden in code vereist doorgaans == null of isNotBlank cheques. Java 8 biedt nu de Optioneel class om deze controles eleganter af te handelen, en de functionele Java-bibliotheek biedt een vergelijkbare constructie om ontbrekende gegevens netjes af te handelen via zijn Option-klasse:

public void checkOptions_givenOptions_returnResult () {Option n1 = Option.some (1); Optie n2 = Option.some (2); Optie n3 = Option.none (); F. functie = i -> i% 2 == 0? Option.some (i + 100): Option.none (); Optie result1 = n1.bind (functie); Optie result2 = n2.bind (functie); Optie result3 = n3.bind (functie); assertEquals (Option.none (), resultaat1); assertEquals (Option.some (102), result2); assertEquals (Option.none (), resultaat3); }

9. Een set verkleinen met behulp van een functie

Ten slotte kijken we naar functionaliteit om een ​​set te verkleinen. "Een set verkleinen" is een mooie manier om te zeggen "het in één waarde oprollen".

De functionele Java-bibliotheek verwijst naar deze functionaliteit als vouwen.

Er moet een functie worden gespecificeerd om aan te geven wat het betekent om het element te vouwen. Een voorbeeld hiervan is de Gehele getallen. Toevoegen functie om de gehele getallen in een array of lijst te tonen, moeten worden toegevoegd.

Op basis van wat de functie doet bij het vouwen, kan het resultaat verschillen, afhankelijk van of u van rechts of links begint te vouwen. Daarom biedt de functionele Java-bibliotheek beide versies:

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

De eerste vouw naar links voegt gewoon alle gehele getallen toe. Terwijl de tweede eerst een filter toepast en vervolgens de resterende gehele getallen optelt.

10. Conclusie

Dit artikel is slechts een korte inleiding tot de functionele Java-bibliotheek.

Zoals altijd is de volledige broncode van het artikel beschikbaar op GitHub.


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