2016-12-25 2 views
12

Ich habe einen Strom von BiFunctions, die ich auf eine einzige BiFunction reduzieren möchte.Zusammensetzung der BiFunctions

Um genauer zu sein, die ich einen Strom von BiFunctions haben

BiFunction<x,y,y> 

Wo x und y die Typen der Argumente bezeichnen.

Angenommen, ich habe zwei Funktionen

f (x, y) -> y 
g (x, y) -> y 

Ich möchte, dass sie die Funktion

h(x, y) -> f(x, g(x, y)) 

Ist dies möglich, mit Hilfe von Java 8-Streams komponieren, und wenn nicht, was die eleganteste Art und Weise wäre Abgesehen davon, einfach alle verfügbaren Funktionen zu durchlaufen und sie auf andere Weise zu komponieren?

+1

Sie suchen nach Stream.reduce, zu dem Sie ein Lambda geben müssen, das f und g nimmt und h zurückgibt. –

Antwort

12

Mit x=Integer und y=String, könnten Sie f und g als definieren:

BiFunction<Integer, String, String> f = (i, s) -> i + "-f-" + s; 
BiFunction<Integer, String, String> g = (i, s) -> i + "-g-" + s; 

Und die h Funktion eingebaut werden, um eine Reduktion unter Verwendung von:

BiFunction<Integer, String, String> h = Stream.of(f, g) 
     .reduce((f_, g_) -> (i, s) -> f_.apply(i, g_.apply(i, s))) 
     .get(); //we know the stream is not empty so we can call get directly 

Wenn Sie h-1 und "s" gelten Es wird 1-f-1-g-s zurückgegeben.

+2

Beachten Sie, dass "Stream.of (f, g) .reduce ((f_, g_) -> ...' überflüssig ist, aber in diesem Fall erlaubt es Ihnen, auf mehr als zwei Eingabefunktionen zu verallgemeinern. – immibis

+3

Ja, das ist die Idee - Mit nur zwei Funktionen gibt es keine Notwendigkeit für einen Stream. – assylias

8

Als leichte Modifikation der answer by assylias: Je nach Anwendungsmustern, können Sie auch die Stream#reduce Methode verwenden, die ein Identität als erstes Argument übernimmt, die in diesem Fall die „Identität BiFunction“ ist (eigentlich ein Projektion auf das zweite Argument).

+0

Gibt es einen Vorteil gegenüber der angenommenen Antwort neben dem können wir den get() Aufruf? – lup3x

+3

Es hängt davon ab: Wenn Sie eine Funktion wie 'BiFunction komponieren wollen (Stream > stream) ', dann könnte * man * nicht wissen, ob der Stream leer ist oder nicht.So müßte man zuerst' Optional' prüfen um zu sehen, ob es leer ist.Ich denke mit der "identity" -Funktion Für diesen Fall ist das vernünftig und praktisch. – Marco13