JAVA-C1
Funktionale Programmierung
@! Spungmarken in allen Pages testen!
Funktionale Programmierung
Function as Value
Pure Function
Higher-Order Functions
@FunctionalInterface Annotation
Methoden-Referenzen
Bedeutung von Stream API
Optional als neuer Typ
Zusammengefasst
Funktionales Interface
@FunctionalInterface
Lambda-Expressions
Simple / Komplex
Scope
Custom-Functional-Interfaces
Custom-Functional-Interfaces
Custom-Functional-Interfaces
Herkömmliches Interface
Funktionales Interface IRechnerDouble definieren und verwenden.
Generische funktionale Interfaces
@FunctionalInterface
Beispiele mit IRechnerGenericFlexible<Integer> r = ..
Beispiel: Lambda-Rechenoperationen mit Objekten
Beispiel: IRead T, IUpdate T, I Read T, IPrint T
Predefined Functional Interfaces
Overview
Function
BiFunction
Predicate
Supplier
Consumer
Diagramm aller Predefined Functional Interfaces
Diagramm Converter Interfaces
ToIntFunction/ToIntBiFunction
DoubleBinaryOperator (EXAMPLE)
@! Sprunmarken ergänzen/testen!
plugin-and-command-pattern-architecture
Beispiel/Collection
Funktionale Interfaces
Predefined Functional Interfaces | Overview
In diesem Themenblock geben wir einen Gesamtüberblick
über im Package java.util.function bereits
vordefinierten funktionalen Interfaces, erklären die Bedeutung von
Suppliern, Predicates, Functions, Consumern sowie anderer Typen
und zeigen examplarisch, wie diese funktionieren.
All diese vordefinierten funktionalen Interfaces sind zentraler Bestandteil der Java Collection Stream API. Dieses führt dazu, dass jeder Entwickler in diesem Kontext sowohl für Methoden-Referenzen als auch für die Programmierung von Lambda-Expressions diese vordefinierten Interfaces kennen sollte, weil die Operatoren der APIs Werte dieser Typen fordern.
Prinzip
Predefined Functional Interfaces | Liste
Bereits ab Java 8 verfügt Java über mehrere Dutzend vordefinierte funktionale Interfaces vom Supplier über Predicates, Functions, Operators bis Consumers. Die Liste ist etwas länger, das Prinzip ist aber schnell zu verstehen.
Damit Entwickler für die gängigen primitiven Datentypen wie
int, double,
boolean sowie normale Objekte
als Object die entsprechenden
funktionalen Interfaces finden, sind für fast jeden dieser 4
Typen die entsprechenden Varianten geschaffen worden.
Darüber hinaus wird berücksichtigt, ob Function- oder Consumer-Interfaces nun eigentlich einen oder zwei Input-Parameter haben.
BiConsumer<T, U>
BiFunction<T, U, R>
BinaryOperator<T>
BiPredicate<T, U>
BooleanSupplier
Consumer<T>
DoubleBinaryOperator
DoubleConsumer
DoubleFunction<R>
DoublePredicate
DoubleSupplier
DoubleToIntFunction
DoubleToLongFunction
DoubleUnaryOperator
Function<T, R>
IntBinaryOperator
IntConsumer
IntFunction<R>
IntPredicate
IntSupplier
IntToDoubleFunction
IntToLongFunction
IntUnaryOperator
LongBinaryOperator
LongConsumer
LongFunction<R>
LongPredicate
LongSupplier
LongToDoubleFunction
LongToIntFunction
LongUnaryOperator
ObjDoubleConsumer<T>
ObjIntConsumer<T>
ObjLongConsumer<T>
Predicate<T>
Supplier<T>
ToDoubleBiFunction<T, U>
ToDoubleFunction<T>
ToIntBiFunction<T, U>
ToIntFunction<T>
ToLongBiFunction<T, U>
ToLongFunction<T>
UnaryOperator<T>
Diagramm
Predefined Functional Interfaces | Diagramm
In einem Diagramm erkennt man leichter den Zusammenhang zwischen Einsatzbereich eines funktionalen Interfaces und dem zugehörigen Typ.
ObjectIntConsumer erwartet als
ersten Parameter noch ein Objekt. Einige Funktionale Interfaces
wie DoubleToIntFunction oder
ToIntFunction werden
als Converter bezeichnet
und werden in einem späteren Kapitel besonders
behandelt.
Predicate T
Eine Predicate<T> prüft Bedingungen
basierend auf einem einzigen Parameter des Typs T
und gibt ein Boolean mit dem Wert true oder
false zurück.
Predicate-Interfaces in den verschiedenen Varianten werden in vielen Operatoren der Stream-API wie beispielsweise beim Mapping verwendet, um schnell entscheiden zu können, ob ein Element aus einem Stream nun ignoriert oder in den nächsten Stream mit übernommen werden wird.
Function_TR
Eine Function<T,R> Instanz transformiert
einen Eingabewert des Typs T in einen Ausgabewert
des Return-Types R.
Die Besonderheit der Function-Typen besteht darin, dass der Input-Parameter-Typ bzw. bei einer BiFunction die zwei Input-Parameter-Typen andere Typen sein können als der Return-Type. In diesem Aspekt unterscheiden sich deshalb Function und BiFunction von UnaryOperator-Interfaces.
BiFunction<T,U,R>
Eine BiFunction<T,U,R> ermöglicht die Verarbeitung
von zwei Werten der Typparameter T und U und
gibt abschließend einen Wert des Typs
R zurück.
DoubleBinaryOperator
package com.stuelken.java.b3.functionalinterface.e04_predefined;
import java.util.function.DoubleBinaryOperator;
/**
* Beispiel für {@link DoubleBinaryOperator}
*
* @author t2m
*
*/
public class DoubleBinaryOperatorExample {
public static void main(String[] args) {
doubleBinaryOperatorExample();
}
/**
* Methode welche einen Array mit Zahlenpaaren über einen {@link DoubleBinaryOperator} für eine
* Funktion, welche zwei Werte multiplizieren kann, Wertepaar für Wertepaar multipliziert und
* ausgibt.
*
* {@index "Example FunctionalInterface/DoubleBinaryOperator/DoubleBinaryOperator.applyAsDouble(a,b)
*
*/
public static void doubleBinaryOperatorExample() {
// Multipliziert schlichtweg zwei Werte.
DoubleBinaryOperator multiplyFunction = (a, b) -> a * b;
// Array von Operanden für die Multiplikation
double[][] pairs = { //
{ 1.5, 2.0 }, //
{ 3.1, 4.2 }, //
{ 5.0, 6.5 }, //
{ 7.2, 8.3 }, //
{ 9.9, 10.1 } //
};
// Schleife über einen zweidimensionalen Array
for (double[] p : pairs) {
double result = multiplyFunction.applyAsDouble(p[0], p[1]);
System.out.println("// " + p[0] + " * " + p[1] + " = " + result);
}
}
}
//1.5 * 2.0 = 3.0
//3.1 * 4.2 = 13.020000000000001
//5.0 * 6.5 = 32.5
//7.2 * 8.3 = 59.760000000000005
//9.9 * 10.1 = 99.99
Consumer_T
Als Consumer bezeichnet man diejenigen Funktionen, welche zwar einen Parameter haben und damit einen Input erhalten, letztendlich aber mangels eines return-Statements keinen Output haben.
Consumer «verbrauchen» quasi die Daten, welche Sie beispielsweise aus einem Datenstrom als Wert erhalten haben und werden deshalb oft als Funktionales Interfaces als Typ für Aggregate-Operationen gefordert.
Ein Consumer<T> akzeptiert einen Parameter
des über den einzigen Typ-Parameter angegeben Typs T
und führt Operationen durch, ohne einen Rückgabewert zu liefern.
BiConsumer TU
Eine BiConsumer<T,U> ermöglicht die Verarbeitung
von zwei Werten der Typparameter T und U,
gibt aber abschließend keinen Wert zurück.
BiConsumer<T, U>
Converter
Einige Funktionale Interfaces dienen der Konvertierung von Daten im Input in einen anderen Datentyp im Output. Das java.util.function Package bietet für die primitiven Typen int, double, long für Zahlen die entsprechenden Interfaces.
ToIntBiFunction
Converter
Kurzer Überblick mit ein paar Beispielen.
DoubleBinaryOperator
package com.stuelken.java.b3.functionalinterface.e04_predefined;
import java.util.function.DoubleBinaryOperator;
/**
* Beispiel für {@link DoubleBinaryOperator}
*
* @author t2m
*
*/
public class DoubleBinaryOperatorExample {
public static void main(String[] args) {
doubleBinaryOperatorExample();
}
/**
* Methode welche einen Array mit Zahlenpaaren über einen {@link DoubleBinaryOperator} für eine
* Funktion, welche zwei Werte multiplizieren kann, Wertepaar für Wertepaar multipliziert und
* ausgibt.
*
* {@index "Example FunctionalInterface/DoubleBinaryOperator/DoubleBinaryOperator.applyAsDouble(a,b)
*
*/
public static void doubleBinaryOperatorExample() {
// Multipliziert schlichtweg zwei Werte.
DoubleBinaryOperator multiplyFunction = (a, b) -> a * b;
// Array von Operanden für die Multiplikation
double[][] pairs = { //
{ 1.5, 2.0 }, //
{ 3.1, 4.2 }, //
{ 5.0, 6.5 }, //
{ 7.2, 8.3 }, //
{ 9.9, 10.1 } //
};
// Schleife über einen zweidimensionalen Array
for (double[] p : pairs) {
double result = multiplyFunction.applyAsDouble(p[0], p[1]);
System.out.println("// " + p[0] + " * " + p[1] + " = " + result);
}
}
}
//1.5 * 2.0 = 3.0
//3.1 * 4.2 = 13.020000000000001
//5.0 * 6.5 = 32.5
//7.2 * 8.3 = 59.760000000000005
//9.9 * 10.1 = 99.99
UIO3 Es ist einfacher als Du denkst.
Stelle noch heute Deine Anfrage.


