Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Industrial programming >> Java

Java Lambda-expressies: Van basis tot Stream API

Java Lambda-expressies onder de knie

Verkent Java's lambda-expressies, functionele interfaces, generics en de Stream API met duidelijke voorbeelden.

Java 8 introduceerde lambda-expressies om de expressieve kracht van de taal te vergroten, waardoor ontwikkelaars meer beknopte en leesbare code kunnen schrijven.

Voordat we in lambdas duiken, is het essentieel om functionele interfaces te begrijpen, de ruggengraat van lambda-implementatie.

Wat is een functionele interface?

Een functionele interface is een Java-interface die precies één abstracte methode bevat. Deze enkele methode definieert het beoogde doel van de interface.

De Runnable-interface uit java.lang is een klassiek voorbeeld, met alleen de run()-methode.

Voorbeeld 1: Een functionele interface definiëren

import java.lang.FunctionalInterface;

@FunctionalInterface
public interface MijnInterface {
    // Enkele abstracte methode
    double getWaarde();
}

Hier is MijnInterface geannoteerd met @FunctionalInterface, wat de compiler dwingt het functionele interface-contract na te leven, wat per ongeluk toevoegen van meerdere abstracte methoden voorkomt. De annotatie is optioneel maar sterk aanbevolen voor duidelijkheid en veiligheid.

In Java 7 werden functionele interfaces aangeduid als Single Abstract Methods (SAMs) en typisch geïmplementeerd met anonieme klassen.

Voorbeeld 2: Een SAM implementeren met een anonieme klasse

public class FunctioneleInterfaceTest {
    public static void main(String[] args) {
        // Anonieme klasse die Runnable implementeert
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Ik heb de Runnable functionele interface geïmplementeerd.");
            }
        }).start();
    }
}

Output:

Ik heb de Runnable functionele interface geïmplementeerd.

Hoewel anonieme klassen boilerplate verminderen ten opzichte van traditionele implementaties, blijft de syntax verbose. Lambda-expressies elimineren de noodzaak voor expliciete methodennamen bij het doorgeven van functionele interfaces als argumenten.

Inleiding tot Lambda-expressies

Een lambda-expressie is in essentie een anonieme methode die een beknopte implementatie levert van de abstracte methode van een functionele interface. Het voert niet onafhankelijk uit; het levert het gedrag voor de interface-methode.

Hoe een lambda-expressie in Java te definiëren

De algemene syntax is:

(parameterlijst) -> lambda-body

->) scheidt de parameterlijst van de body. Hieronder concrete voorbeelden.

Stel we hebben een methode die Pi retourneert:

double getPiWaarde() { return 3.1415; }

Met een lambda:

() -> 3.1415

Zonder parameters is de linkerkant van de pijl leeg, en de rechterkant is de expressie-body die de waarde retourneert.

Typen lambda-bodies

Java lambda-bodies komen in twee vormen:

1. Expressie-body – bevat één expressie.

() -> System.out.println("Lambdas zijn geweldig");

2. Blok-body – in accolades gekapseld, toestaat meerdere statements en een optionele return.

() -> { double pi = 3.1415; return pi; };

Let op: Expressie-bodies vereisen geen expliciete return, blok-bodies wel als een waarde geretourneerd wordt.

Voorbeeld 3: Lambda-expressie in de praktijk

Laten we een Java-programma schrijven dat Pi retourneert met een lambda-expressie.

import java.lang.FunctionalInterface;

@FunctionalInterface
interface MijnInterface {
    double getPiWaarde();
}

public class Main {
    public static void main(String[] args) {
        MijnInterface ref = () -> 3.1415;
        System.out.println("Waarde van Pi = " + ref.getPiWaarde());
    }
}

Output:

Waarde van Pi = 3.1415

Belangrijkste punten:

  • MijnInterface definieert één abstracte methode
  • Een referentie naar MijnInterface wordt gedeclareerd maar niet direct geïnstantieerd
  • De lambda-expressie levert de implementatie voor getPiWaarde()
  • Het aanroepen van ref.getPiWaarde() triggert de lambda-body

Lambda-expressies met parameters

Net als methoden kunnen lambdas parameters accepteren. Voorbeeld:

(n) -> (n % 2) == 0

Deze lambda checkt of het invoer-integer even is.

Voorbeeld 4: Een string omkeren met een geparametriseerde lambda

@FunctionalInterface
interface MijnInterface {
    String omkeren(String s);
}

public class Main {
    public static void main(String[] args) {
        MijnInterface ref = (str) -> {
            String resultaat = "";
            for (int i = str.length() - 1; i >= 0; i--) {
                resultaat += str.charAt(i);
            }
            return resultaat;
        };
        System.out.println("Lambda omgekeerd = " + ref.omkeren("Lambda"));
    }
}

Output:

Lambda omgekeerd = adbmaL

Generieke functionele interface

Functionele interfaces kunnen generiek zijn, zodat ze op elk datatype kunnen opereren. Bijvoorbeeld:

@FunctionalInterface
interface MijnInterface<T> {
    T func(T t);
}

Voorbeeld 5: Generieke lambdas voor Strings en Integers

public class Main {
    public static void main(String[] args) {
        // String omkeren
        MijnInterface<String> omkeren = (str) -> {
            String resultaat = "";
            for (int i = str.length() - 1; i >= 0; i--) {
                resultaat += str.charAt(i);
            }
            return resultaat;
        };
        System.out.println("Lambda omgekeerd = " + omkeren.func("Lambda"));

        // Integer faculteit
        MijnInterface<Integer> faculteit = (n) -> {
            int resultaat = 1;
            for (int i = 1; i <= n; i++) {
                resultaat *= i;
            }
            return resultaat;
        };
        System.out.println("faculteit van 5 = " + faculteit.func(5));
    }
}

Output:

Lambda omgekeerd = adbmaL
faculteit van 5 = 120

Lambda-expressies en de Stream API

Het java.util.stream-pakket, geïntroduceerd in JDK 8, stelt ontwikkelaars in staat om functionele-stijl operaties op collecties uit te voeren: filteren, mappen, reduceren, sorteren, en meer.

Bekijk een lijst met plaatsnamen, elk voorzien van een land-prefix. Met streams en lambdas kun je efficiënt data extraheren en manipuleren.

Voorbeeld 6: Stream-verwerking met lambdas

import java.util.ArrayList;
import java.util.List;

public class StreamMain {
    static List<String> plaatsen = new ArrayList<>();

    public static List<String> getPlaatsen() {
        plaatsen.add("Nepal, Kathmandu");
        plaatsen.add("Nepal, Pokhara");
        plaatsen.add("India, Delhi");
        plaatsen.add("USA, New York");
        plaatsen.add("Africa, Nigeria");
        return plaatsen;
    }

    public static void main(String[] args) {
        List<String> mijnPlaatsen = getPlaatsen();
        System.out.println("Plaatsen uit Nepal:");
        mijnPlaatsen.stream()
            .filter(p -> p.startsWith("Nepal"))
            .map(p -> p.toUpperCase())
            .sorted()
            .forEach(p -> System.out.println(p));
    }
}

Output:

Plaatsen uit Nepal:
NEPAL, KATHMANDU
NEPAL, POKHARA

Hier accepteert de ketting van stream-operaties – filter, map, sorted, forEach – elk een lambda, wat boilerplate drastisch vermindert ten opzichte van pre-Java-8 oplossingen.

Java

  1. C#-interfaces onder de knie: definitie, implementatie en praktische use cases
  2. Java-operators beheersen: typen, syntax en praktische voorbeelden
  3. Java Expressies, Statements en Blokken begrijpen
  4. Java interfaces meesteren: concepten, implementatie en best practices
  5. Java Try-with-resources meesteren: automatische resource management uitgelegd
  6. Java Annotaties uitgelegd: typen, plaatsing en praktische voorbeelden
  7. Interface vs Abstracte Klasse in Java: De Juiste Abstractie Kiezen
  8. Java Reguliere Expressies: Patroonherkenning onder de knie krijgen met java.util.regex
  9. Java Interfaces begrijpen: Definities, Gebruik en Best Practices
  10. Java 9 Private Interface Methods: Encapsulatie & herbruik verbeteren
  11. Java 8 Lambda Expressies beheersen: Gids voor functioneel programmeren