---
title: 'Funktionale Schnittstelle in Java 8 aus java.util.function'
url: 'https://www.tutego.de/blog/javainsel/2014/03/funktionale-schnittstelle-aus-dem-java-util-function-paket'
markdown: 'https://www.tutego.de/blog/javainsel/2014/03/funktionale-schnittstelle-aus-dem-java-util-function-paket.md'
date: '2014-03-30'
description: 'Funktionen realisieren Abbildungen und da es verschiedene Arten von Abbildungen geben kann, bietet die Java Standardbibliothek im Paket java.util.function für die häufigsten Fälle funktionale Schnittstellen an. Ein erster Überblick: Schnittstelle**Abbildung**Consumer<T>(T) → voidDoubleConsume…'
taxonomy:
  category:
    - Insel
    - 'Java 8'
---

# Funktionale Schnittstelle in Java 8 aus java.util.function

![Illustration einer tropischen Insel mit Palmen und einem hohen Berg](https://www.tutego.de/blog/javainsel/user/themes/tutego/images/insel-cover.jpg)# Java Blog für Programmierer

[Java Blog für Programmierer](https://www.tutego.de/blog/javainsel/)

## Funktionale Schnittstelle in Java 8 aus java.util.function

30.03.2014 · [Christian Ullenboom](https://www.tutego.de/blog/javainsel/author/admin/)

Funktionen realisieren Abbildungen und da es verschiedene Arten von Abbildungen geben kann, bietet die Java Standardbibliothek im Paket `java.util.function` für die häufigsten Fälle funktionale Schnittstellen an. Ein erster Überblick:

**Schnittstelle\*\***Abbildung\*\*`Consumer`<T>(T) → `voidDoubleConsumer(double)` → `voidBiConsumer`<T, U>(T, U) → `voidSupplier`<T>() → TBooleanSupplier() → `booleanPredicate`<T>(T) → `booleanLongPredicate(long)` → `booleanBiPredicate`<T, U>(T, U) → `booleanFunction`<T, R>(T) → RLongToDoubleFunction(long) → `doubleBiFunction`<T, U, R>(T, U) → RUnaryOperator<T>(T) → TDoubleBinaryOperator(double) → boolean

*Beispiele einiger vordefinierter funktionaler Schnittstellen*

### Blöcke mit Code und die funktionale Schnittstelle `java.util.function.Consumer`

Anweisungen von Code lassen sich in eine Methode eines Objekts setzen und auf diese Weise weitergeben. Das ist eine häufige Notwendigkeit, für die das Paket `java.util.function` eine einfache funktionale Schnittstelle `Consumer` vorgibt, die einen Konsumenten repräsentiert, der Daten annimmt und dann verbraucht (konsumiert).

```
interface java.util.function.Consumer<T>
```

- `void accept(T t)`Führt Operationen mit der Übergabe t durch.
- `default Consumer<T> andThen(Consumer<? super T> after)`Liefert einen neuen Consumer, der erst den aktuellen Consumer ausführt und dann after.

Die `accept(…)`-Methode bekommt ein Argument – wobei die Implementierung natürlich nicht zwingend darauf zurückgreifen muss – und liefert keine Rückgabe. Transformationen sind damit nicht möglich, denn nur über Umwege kann der Konsument die Ergebnisse speichern, und dafür ist die Schnittstelle nicht gedacht. `Consumer`-Typen sind eher gedacht als Endglied einer Kette, in der zum Beispiel Dateien in eine Datei geschrieben werden, die vorher verarbeitet wurden. Diese Seiteneffekte sind beabsichtigt, da sie nach einer Kette von seiteneffektfreien Operationen stehen.

Immer repräsentieren Konsumenten Code, und eine API kann nun einfach einen Code-Block nach der Art `doSomethingWith(myConsumer)` annehmen, und ihn etwa in einem Hintergrund-`Thread` abzuarbeiten, oder wiederholend auszuführen, oder nach einer erlaubten Maximaldauer abbrechen, oder die Zeit messen, oder, oder, oder …

Beispiel: Implementiere einen `Consumer`-Wrapper, der die Ausführungszeit eines anderen Konsumenten loggt.

```java
import java.util.function.*;
```

```java
import java.util.logging.Logger;
```

```java
class Consumers {
```

```java
  public static  Consumer measuringConsumer( Consumer block ) {
```

```java
    return t -> {
```

```java
      long start = System.nanoTime();
```

```java
      block.accept( t );
```

```java
      long duration = System.nanoTime() - start;
```

```java
      Logger.getAnonymousLogger().info( "Ausführungszeit (ns): " + duration );
```

```java
    };
```

```java
  }
```

```java
}
```

Folgender Aufruf zeigt die Nutzung:

```java
Consumer wrap = measuringConsumer( Void -> System.out.println( "Test" ) );
wrap.accept( null );
```

Was wir hier implementiert haben ist ein Beispiel vom Execute-Around-Method Muster, bei dem wir um einen Block Code noch etwas anderes legen.

#### Typ `Consumer` in der API

In der Java-API zeigt sich der Typ `Consumer` in der Regel als Argument einer Methode `forEach(Consumer)`, die Datenquellen abläuft und für jedes Element `accept(…)` aufruft. Interessant ist die Methode am Typ `Iterable`, denn die wichtigen `Collection`-Datenstrukturen wie `ArrayList` implementieren diese Schnittstelle. So lässt sich einfach über alle Daten laufen und ein Stück Code für jedes Element ausführen. Auch `Iterator` hat eine vergleichbare Methode, da heißt sie `forEachRemaining(Consumer)` – das „Remaining“ macht deutlich, dass der `Iterator` schon ein paar `next()`-Aufrufe erlebt haben könnte, und die Konsumenten daher nicht zwingend die ersten Elemente mitbekommen.

Beispiel: Gib jedes Element einer Liste auf der Konsole aus:

```java
Arrays.asList( 1, 2, 3, 4 ).forEach( System.out::println );
```

### `Supplier`

Ein `Supplier` (auch Provider genannt) ist eine Fabrik und sorgt für Objekte. In Java deklariert das Paket `java.util.function` die funktionale Schnittstelle `Supplier` für Objektgeber:

```
interface java.util.function.Supplier<T>
```

- `T get()`Führt Operationen mit der Übergabe t durch.

Weitere statische oder Default-Methoden deklariert `Supplier` nicht. Was `get()` nun genau liefert ist Aufgabe der Implementierung und ein Interna. Es können neue Objekte sein, immer die gleichen Objekte (Singleton), oder Objekte aus einem Cache.

### Prädikate und `java.util.function.Predicate`

Ein Prädikat ist eine Aussage über einen Gegenstand, die wahr oder falsch ist. Die Frage mit Character.`isDigit`(‚a‘), ob das Zeichen „a“ eine Ziffer ist, wird mit falsch beantwortet – `isDigit` ist also ein Prädikat, weil es über einen Gegenstand, einem Zeichen, eine Wahrheitsaussage fällen kann.

Flexibler sind Prädikate, wenn sie als Objekte repräsentiert werden, weil sie dann an unterschiedliche Stellen weitergegeben werden können. Wenn etwa über ein Prädikat bestimmt wird, was aus einer Sammlung gelöscht werden soll oder ob mindestens ein Element in einer Sammlung ist, welches ein Prädikat erfüllt.

Das `java.util.function`-Paket[\[1\]](file:C:/Users/Christian%20Ullenboom/Dropbox/Eigene%20Dokumente/Insel/todo/2.Funktionale%20Programmierung,%20ISP,%20zu%20JM.doc#_ftn1) deklariert eine flexible funktionale Schnittstelle `Predicate` auf folgende Weise:

```
interface java.util.function.Predicate<T>
```

- `boolean test(T t)`Führt einen Test auf t durch und liefert true, wenn das Kriterium erfüllt ist, sonst false.

Beispiel: Der Test, ob ein Zeichen eine Ziffer ist, kann durch Prädikat-Objekte nun auch anders durchgeführt werden:

```java
Predicate isDigit = c -> Character.isDigit( c );  // kurz: Character::isDigit
System.out.println( isDigit.test('a') );  // false
```

Hätte es die Schnittstelle `Predicate` schon früher in Java 1.0 gegeben, hätte es der Methode `Character.isDigit(…)` gar nicht bedurft, es hätte auch ein `Predicate`<Character> als statische Variable in der Klasse Character geben können, sodass ein Test dann geschrieben würde als Character.IS`\_DIGIT.test(…)`oder als Rückgabe von einer Methode`Predicate`&lt;Character&gt;`isDigit()`, mit der Nutzung`Character.isDigit().test(…)`. Es ist daher gut möglich, dass sich in Zukunft die API dahingehend verändert, dass Aussagen auf Gegenständen mit Wahrheitsrückgabe nicht mehr als Methoden bei den Klassen realisiert werden, sondern als Prädikat-Objekte angeboten werden. Aber Methoden-Referenzen geben zum Glück die Flexibilität, dass problemlos existierende Methoden als Lambda-Ausdrücke genützt werden können und so kommen wir wieder von Methoden zu Funktionen.

#### Typ `Predicate` in der API

Es gibt in der Java-API einige Stellen, an denen `Predicate`-Objekte genutzt werden:

- Als Argument für Lösch-Methoden, um in Sammlungen Elemente zu spezifizieren, die gelöscht oder nach denen gefiltert werden sollen.
- Bei den Default-Methoden der `Predicate`-Schnittstelle selbst, um Prädikate zu verknüpfen.
- Bei regulären Ausdrücken: ein Pattern liefert mit `asPredicte()` ein `Predicate` für Tests
- In der `Stream`-API, bei der Objekte beim Durchlaufen des Stroms über ein Prädikat identifiziert werden, um sie etwa auszufiltern.

Beispiel: Lösche aus einer Liste mit Zeichen alle, die Ziffern sind (es bleiben nur Zeichen übrig, etwa Buchstaben).

```java
Predicate isDigit = Character::isDigit;
List list = new ArrayList( Arrays.asList( 'a', '1' ) );
list.removeIf( isDigit );
```

#### Default-Methoden von `Predicate`

Es gibt eine Reihe von Default-Methoden, die die funktionale Schnittstelle `Predicate` anbietet. Zusammenfassend:

```
interface java.util.function.Predicate<T>
```

- `default Predicate<T> negate()`Liefert vom aktuellen Prädikat eine Negation. Implementiert als return t -> ! test(t);.
- `default Predicate<T> and(Predicate<? super T> p)`
- `default Predicate<T> or(Predicate<? super T> p)`Und/Oder-Verknüpfen das aktuelle Prädikat mit einem anderen Prädikat.
- `static <T> Predicate<T> isEqual(Object targetRef)`Liefert ein neues Prädikat welches einen Gleichheitstest mit targetRef vornimmt, im Grunde return ref -> Objects.equals(ref, targetRef).

Beispiel: Lösche aus einer Liste mit Zeichen alle die, die *keine* Ziffern sind.

```java
Predicate isDigit = Character::isDigit;
Predicate isNotDigit = isDigit.negate();
List list = new ArrayList( Arrays.asList( 'a', '1' ) );
list.removeIf( isNotDigit );
```

#### Prädikate aus Pattern

Seit Java 8 liefert die Pattern-Methode `asPredicate()` ein `Predicate`<`String`>, so dass ein regulärer Ausdruck als Kriterium zum Beispiel zum Filtern oder Löschen von Einträgen in Datenstrukturen genutzt werden kann.

### Funktionen und die allgemeine funktionale Schnittstelle `java.util.function.Function`

Funktionen im Sinne der funktionalen Programmierung können in verschiedenen Bauarten vorkommen: mit Parameterliste / Rückgabe oder ohne. Doch im Grunde sind es Spezialformen, und die funktionale Schnittstelle `java.util.function.Function` ist die allgemeinste, die zu einem Argument ein Ergebnis liefert.

```
interface java.util.function.Function<T, R>
```

- `R apply(T t)`Wendet eine Funktion an und liefert zur Eingabe t eine Rückgabe.

Beispiel:Eine Funktion zur Bestimmung des Maximums:

```java
Function max = a -> Math.abs( a );  // alternativ Math::abs
System.out.println( max.apply( -12. ) );  // 12.0
```

Auch bei Funktionen ergibt sich für das API-Design ein Spannungsfeld, denn im Grunde müssen „Funktionen“ nun gar nicht mehr als Methoden angeboten werden, sondern Klassen könnten sie auch als `Function`-Objekte anbieten. Doch da Methoden-Referenzen problemlos die Brücke von Methodennamen zu Objekten schlagen, fahren Entwickler mit klassischen Methoden ganz gut.

#### Typ `Function` in der API

Die `Stream`-API ist der größte Nutznießer vom `Function`-Typ. Es finden sich einige wenige Beispiele bei Objekt-Vergleichen (`Comparator`), im Paket für Nebenläufigkeiten und bei Assoziativspeichern. Im Abschnitt über die `Stream`-API werden wir daher viele weitere Beispiele kennenlernen.

Beispiel: Ein Assoziativspeicher soll als Cache realisiert werden, der zu Dateinamen den Inhalt assoziiert. Ist zu dem Schlüssel (dem Dateinamen) noch kein Inhalt vorhanden, soll dieser in den Assoziativspeicher gelegt werden.

```java
class FileCache {
```

```java
  private Map map = new HashMap();
```

```java
  public byte[] getContent( String filename ) {
```

```java
    return map.computeIfAbsent( filename, file -> {
```

```java
      try {
```

```java
        return Files.readAllBytes( Paths.get( file ) );
```

```java
      } catch ( IOException e ) { throw new UncheckedIOException( e ); }
```

```java
    } );
```

```java
  }
```

```java
}
```

Zu der Methode kommt das Kapitel über Datenstrukturen noch einmal zurück, das Beispiel soll nur eine Idee geben, dass Funktionen an andere Funktionen übergeben werden – hier eine `Function`<`String`, byte\[\]) an `computeIfAbsent(…)`. Sobald an den Datei-Cache der Aufruf `getContent(String)`geht, wird dieser die `Map` fragen und wenn diese zu dem Schlüssel keinen Wert hat, wird sie den Lambda-Ausdruck auswerten, um zu dem Dateinamen den Inhalt zu liefern.

#### Getter-Methoden als `Function` über Methoden-Referenzen

Methoden-Referenzen gehören zu den stärksten Sprachmitteln von Java 8. In Kombination mit Gettern ist ein Muster abzulesen, welches oft in Code zu sehen ist. Zunächst noch einmal zur Wiederholung von `Function` und der Nutzung bei Methoden-Referenzen:

```java
Function func2a = (String s) -> s.toUpperCase();
```

```java
Function func2b = String::toUpperCase;
```

```text

```

```java
Function func1a = (Point p) -> p.getX();
```

```java
Function func1b = Point::getX;
```

```text

```

```java
System.out.println( func2b.apply( "jocelyn" ) );         // JOCELYN
```

```java
System.out.println( func1b.apply( new Point( 9, 0 ) ) ); // 9.0
```

Dass `Function` auf die gegebene Methoden-Referenz passt, ist auf den ersten Blick unverständlich, da die Signaturen von `toUpperCase()` und `getX()` keinen Parameter deklarieren, also im üblichen Sinne keine Funktionen sind, wo etwas reinkommt und wieder rauskommt. Wir haben es hier aber mit einem speziellen Fall zu tun, denn die in der Methoden-Referenz genannten Methoden sind a) nicht statisch – wie Math::max – und b) es ist auch keine Referenz – wie System.out::print – im Spiel, sondern hier wird der Compiler eine Objektmethode auf genau dem Objekt aufrufen was als erstes Argument der funktionalen Schnittstelle übergeben wurde. (Diesen Satz bitte zweimal lesen.)

Damit ist `Function` ein praktischer Typ bei allen Szenarien, bei denen irgendwie über Getter Zustände erfragt werden, wie es etwa bei einem `Comparator` öfters vorkommt. Hier ist eine statische Methode – die Generics einmal ausgelassen – `Comparator`<…> `Comparator`.comparing(`Function`<…> `keyExtractor`) sehr nützlich.

Beispiel: Besorge eine Liste von Pakten, die vom Klassenlader zugänglich sind, und sortiere sie nach Namen:

```java
List list = Arrays.asList( Package.getPackages() );
Collections.sort( list, Comparator.comparing( Package::getName ) );
System.out.println( list ); // [package java.io, ... sun.util.locale ...
```

#### Default-Methoden in `Function`

Die funktionale Schnittstelle schreibt nur eine Methode `apply(…)` vor, deklariert jedoch noch drei zusätzliche Default-Methoden:

```
interface java.util.function.Function<T,R>
```

- `static <T> Function<T,T> identity()`Liefert eine neue Funktion, die immer die Eingabe als Ergebnis liefert.
- `default <V> Function<T,V> andThen(Function<? super R,? extends V> after)`Entspricht t -> after.apply(apply(t)).
- `default <V> Function<V,R> compose(Function<? super V,? extends T> before)`Entspricht v -> apply(before.apply(v)).

Die Methoden `andThen(…)` und `compose(…)` unterscheiden sich also darin, in welcher Reihenfolge die Funktionen aufgerufen werden. Das Gute ist, dass die Parameternamen („before“, „after“) klarmachen, was hier in welcher Reihenfolge aufgerufen wird, wenn auch selbst „compose“ wenig aussagt.

#### `Function` vs. Consumer/Predicate , `UnaryOperator`

Im Grunde lässt sich alles als `Function` darstellen, denn

- ein `Consumer`<T> lässt sich auch als `Function`<T,`Void`> verstehen (es geht etwas rein, aber nichts raus),
- ein `Predicate`<T> als `Function`<T,`Boolean`>,
- ein `Supplier`<T> als `Function`<`Void`,T>.

Dennoch erfüllen diese speziellen Typen voll ihren Zweck, denn je genauer der Typ, desto besser.

Es gibt auch eine weitere Schnittstelle im `java.util.function`-Paket, die `Function` spezialisiert und zwar `UnaryOperator`. Ein `UnaryOperator` ist eine spezielle Funktion bei der die Typen für „Eingang“ und „Ausgang“ gleich sind.

```
interface java.util.function.UnaryOperator<T>

extends Function<T,T>
```

- `static <T> UnaryOperator<T> identity()`Liefert den Identitäts-Operator, der alle Eingaben auf die Ausgaben abbildet.

Die generischen Typen machen deutlich, dass der Typ des Methodenparameters gleich dem Ergebnistyp ist. Bis auf `identity()` gibt es keine weitere Funktionalität, die Schnittstelle dient lediglich zur Typdeklaration.

An einigen Stellen der Java-Bibliothek kommt dieser Typ auch vor, etwa bei der Methode `replaceAll(UnaryOperator)` der `List`-Typen.

Beispiel: Verdopple in der Liste jeden Eintrag.

```java
List list = Arrays.asList( 1, 2, 3 );
list.replaceAll( e -> e * 2 );
System.out.println( list );  // [2, 4, 6]
```

### Ein bisschen Bi …

Bi ist eine bekannte lateinische Vorsilbe für „zwei“, was übertragen auf die Typen aus `java.util.function` bedeutet, das statt einem Argument zwei übergeben werden können.

**Typ\*\***Schnittstelle**\*\*OperationKonsumentConsumer<T>void `accept(T t)`BiConsumer<T,**U**>void accept(T t,** U u**)FunktionFunction<T,**R**>R `apply(T t)``BiFunction`<T,**U**,R>R apply(T t,** U u**)PrädikatPredicate<T>boolean `test(T t)`BiPredicate<T,**U**>boolean test(T t,** U u\*\*)

*Ein-/Zwei-Argument Methoden Vergleich*

Die Bi-Typen haben mit den nicht-Bi-Typen keine Typbeziehung.[\[2\]](file:C:/Users/Christian%20Ullenboom/Dropbox/Eigene%20Dokumente/Insel/todo/2.Funktionale%20Programmierung,%20ISP,%20zu%20JM.doc#_ftn2)

#### BiConsumer

Der BiConsumer deklariert die Methode `accept(T, U)` mit zwei Parametern, die jeweils unterschiedliche Typen tragen können. Haupteinsatzpunkt des Typs in der Java Standardbibliothek sind Assoziativspeicher, die Schlüssel und Werte an `accept(…)` übergeben. So deklariert `Map` die Methode:

```
interface java.util.Map<K,V>
```

- `default void forEach(BiConsumer<? super K,? super V> action)`Läuft den Assoziativspeicher ab und ruft auf jedem Schlüssel-Werte-Paar die accept(…)-Methode vom übergebenen BiConsumer auf.

Beispiel: Gib die Temperaturen der Städte aus:

```java
Map map = new HashMap();
map.put( "Manila", 25 )
map.put( "Leipzig", -5 );
map.forEach( (k,v) -> System.out.printf("%s hat %d Grad%n", k, v) );
```

Ein BiConsumer besitzt eine Default-Methode `andThen(…)`, wie auch der `Consumer` sie zur Verkettung deklariert.

```
interface java.util.function.BiConsumer<T,U>
```

- `default BiConsumer<T,U> andThen(BiConsumer<? super T,? super U> after)`Verknüpft den aktuellen BiConsumer mit after zu einem neunen BiConsumer.

#### `BiFunction` und `BinaryOperator`

Eine `BiFunction` ist eine Funktion mit zwei Argumenten, während eine normale `Function` nur ein Argument annimmt.

Beispiel: Nutzung von `Function` und `BiFunction` mit Methoden-Referenzen.

```java
Function sign = Math::abs;
BiFunction max = Math::max;
```

Die Java-Bibliothek greift viel öfters auf `Function` zurück als auf `BiFunction`. Der häufigste Einsatz findet sich in der Standardbibliothek rund um Assoziativspeicher, bei denen Schlüssel und Wert an eine `BiFunction` übergeben werden.

Beispiel: Konvertiere alle assoziierten Werte einer `HashMap` in Großschreibung.

```java
Map map = new HashMap();
map.put( 1, "eins" ); map.put( 2, "zwEi" );
System.out.println( map );  // {1=eins, 2=zwEi}
BiFunction func = (k, v) -> v.toUpperCase();
map.replaceAll( func );
System.out.println( map );  // {1=EINS, 2=ZWEI}
```

Ist bei einer `Function` der Typ derselbe, bietet die Java-API dafür den spezielleren Typ `UnaryOperator`. Sind bei einer `BiFunction` alle drei Typen gleich, bietet sich hier `BinaryOperator` an – zum Vergleich:

```
- interface UnaryOperator<T> extends Function<T,T>
- interface BinaryOperator<T> extends BiFunction<T,T,T>
```

Beispiel: `BiFunction` und `BinaryOperator`:

```java
BiFunction max1 = Math::max;
BinaryOperator             max2 = Math::max;
```

`BinaryOperator` spielt bei sogenannten Reduktionen eine große Rolle, wenn zum Beispiel wie bei max aus zwei Werten einer wird, auch das beleuchtet der Abschnitt über die `Stream`-API später genauer.

Die Schnittstelle `BiFunction` deklariert genau eine Default-Methode:

```
interface java.util.function.BiFunction<T,U,R>

extends Function<T, T>
```

- `default <V> BiFunction<T,U,V> andThen(Function<? super R,? extends V> after)`

`BinaryOperator` dagegen zwei statische Methoden:

```java
public interface java.util.function.BinaryOperator<T>

extends BiFunction<T,T,T>
```

- `static <T> BinaryOperator<T> maxBy(Comparator<? super T> comparator)`
- `static <T> BinaryOperator<T> minBy(Comparator<? super T> comparator)`Liefert einen BinaryOperator, der das Maximum/Minimum bezüglich eines gegebenes comparator liefert.

#### BiPredicate

Ein BiPredicate testet zwei Argumente und verdichtet sie zu einem Wahrheitswert. Wie `Predicate` deklariert auch BiPredicate drei Default-Methoden `and(…)`, `or(…)` und `negate(…)`, wobei natürlich eine statische `isEqual(…)`-Methode wie bei `Predicate` in BiPredicate fehlt. Für BiPredicate gibt es in der Java-Standardbibliothek nur eine Verwendung bei einer Methode zum Finden von Dateien – der Gebrauch ist selten, zudem ja auch ein Prädikat immer einer Funktion mit boolean-Rückgabe ist, sodass es eigentlich für diese Schnittstelle keine zwingende Notwendigkeit gibt.

Beispiel: Bei BiXXX und zwei Argumenten hört im Übrigen die Spezialisierung auf, es gibt keine Typen TriXXX, QuardXXX, …. Das ist in der Praxis auch nicht nötig, denn zum Einen kann oftmals eine Reduktion stattfinden, so ist etwa `max(1, 2,3)` gleich max(1, `max(2, 3)`) und zum Zweiten kann auch der Parametertyp eine Sammlung sein, wie in `Function`<`List`<`Integer`>, `Integer`> max.

### Funktionale Schnittstellen mit Primitiven

Die bisher vorgestellten funktionalen Schnittstellen sind durch die generischen Typparameter sehr flexibel, aber was fehlt, sind Signaturen mit Primitiven – Java hat das „Problem“, dass Generics nur mit Referenztypen funktioniert, nicht aber mit primitiven Typen. Aus diesem Grund gibt es von fast allen Schnittstellen aus dem function-Paket vier Versionen; eine generische für beliebige Referenzen, sowie Versionen für den Typ int, long und double. Die API-Designer wollten gerne die Wrapper-Typen außen vor lassen und gewisse primitive Typen unterstützen.

Die folgende Tabelle gibt einen Überblick über die funktionalen Schnittstellen, die alle keinerlei Vererbungsbeziehungen zu anderen Schnittstellen haben.

**Funktionale Schnittstelle\*\***Funktions-Deskriptor**\*\*XXXSupplier**BooleanSupplierboolean `getAsBoolean()`IntSupplierint `getAsInt()`LongSupplierlong `getAsLong()`DoubleSupplierdouble `getAsDouble()`**XXXConsumer**IntConsumervoid `accept(int value)`LongConsumervoid `accept(long value)`DoubleConsumervoid `accept(double value)`ObjIntConsumer<T>void `accept(T t, int value)`ObjLongConsumer<T>void `accept(T t, long value)`ObjDoubleConsumer<T>void `accept(T t, double value)`**XXXPredicate**IntPredicateboolean `test(int value)`LongPredicateboolean `test(long value)`DoublePredicateboolean `test(double value)`**XXXFunction**DoubleToIntFunctionint `applyAsInt(double value)`IntToDoubleFunctiondouble `applyAsDouble(int value)`LongToIntFunctionint `applyAsInt(long value)`IntToLongFunctionlong `applyAsLong(int value)`DoubleToLongFunctionlong `applyAsLong(double value)`LongToDoubleFunctiondouble `applyAsDouble(long value)`IntFunction<R>R `apply(int value)`LongFunction<R>R `apply(long value)`DoubleFunction<R>R `apply(double value)`ToIntFunction<T>int `applyAsInt(T t)`ToLongFunction<T>long `applyAsLong(T t)`ToDoubleFunction<T>double `applyAsDouble(T t)`ToIntBiFunction<T,U>int `applyAsInt(T t, U u)`ToLongBiFunction<T,U>long `applyAsLong(T t, U u)`ToDoubleBiFunction<T,U>double `applyAsDouble(T t, U u)`**XXXOperator**IntUnaryOperatorint `applyAsInt(int operand)`LongUnaryOperatorlong `applyAsLong(long operand)`DoubleUnaryOperatordouble `applyAsDouble(double operand)`IntBinaryOperatorint `applyAsInt(int left, int right)`LongBinaryOperatorlong `applyAsLong(long left, long right)`DoubleBinaryOperatordouble `applyAsDouble(double left, double right)`

*Spezielle funktionale Schnittstellen für primitive Werte*

#### Statische und Default-Methoden

Einige generisch deklarierte funktionale Schnittstellen Typen besitzen Default-Methoden bzw. statische Methoden besitzen, und ähnliches findet sich auch bei den primitiven funktionalen Schnittstellen wieder:

Die XXXConsumer-Schnittstellen deklarieren default XXXConsumer `andThen(XXXConsumer after)`, aber nicht die ObjXXXConsumer-Typen, sie besitzen keine Default-Methode.

Die XXXPredicate-Schnittstellen deklarieren

- `default XXXPredicate negate()`
- `default XXXPredicate and(XXXPredicate other)`
- default IntPredicate `or(XXXPredicate other)`.

Jeder XXXUnaryOperator besitzt

- `default XXXUnaryOperator andThen(IntUnaryOperator after)`
- default XXXUnaryOperator `compose(XXXUnaryOperator before)` und
- static IntUnaryOperator `identity()`.

`BinaryOperator` hat zwei statischen Methoden `maxBy(…)` und `minBy(…)`, die es nicht in der primitiven Version XXXBinaryOperator gibt, da kein `Comparator` bei primitiven Vergleichen nötig ist.

Die XXXSupplier-Schnittstellen deklarieren keine statische- oder Default-Methoden, genauso wie es auch `Supplier` nicht tut.

---

[\[1\]](file:C:/Users/Christian%20Ullenboom/Dropbox/Eigene%20Dokumente/Insel/todo/2.Funktionale%20Programmierung,%20ISP,%20zu%20JM.doc#_ftnref1) Achtung, in `javax.sql.rowset` gibt es ebenfalls eine Schnittstelle `Predicate`.

[\[2\]](file:C:/Users/Christian%20Ullenboom/Dropbox/Eigene%20Dokumente/Insel/todo/2.Funktionale%20Programmierung,%20ISP,%20zu%20JM.doc#_ftnref2) Irgendwie finden das manche Leser lustig …

Kategorien: [Insel](https://www.tutego.de/blog/javainsel/category/insel/), [Java 8](https://www.tutego.de/blog/javainsel/category/java-8/)

## 2 Kommentare

**Konrad Demmel** · [28.09.2022 12:00](#comment-1073649)

Ein bisschen Bi … Bi ist eine bekannte lateinische Vorsilbe für „zwei“, was übertragen auf die Typen aus java.util.function bedeutet, das statt einem Argument zwei übergeben werden können. richtig: ... dass statt ...

**Michael** · [08.06.2018 18:37](#comment-656748)

Die Abbildung des DoubleBinaryOperator im "ersten Überblick" (erste Tabelle) ist falsch. Sie müsste lauten: (double, double) → double

Die bisherigen Kommentare wurden aus WordPress übernommen. Neue Kommentare sind derzeit geschlossen.

[← Alle Beiträge](https://www.tutego.de/blog/javainsel/)

---

## Navigation

- Previous: [Thema der Woche: Java Mission Control](https://www.tutego.de/blog/javainsel/2014/03/thema-der-woche-java-mission-control.md)
