Java-8-Funktionen - erstellen und dann
Finde ich meine Java-Kenntnisse out-of-date mit Java 8, und es gibt viele neue features für die Sprache, die ich versuche zu lernen. Einer von Ihnen ist Funktionen, insbesondere die compose
und andThen
Methoden.
Ich geschrieben habe ein triviales experiment zum test der Reversibilität der compose
und andThen
:
/** Wraps a value
*/
public class Wrap<T> {
private final T value;
private Wrap(T value) {
this.value = value;
}
public static <T> Wrap<T> of(T value) {
return new Wrap<>(value);
}
}
static void functions() {
Function<Integer,String> itos = i->"'"+i+"'";
Function<String,Wrap<String>> stow = s->Wrap.of(s);
Function<Integer,Wrap<String>> itow = itos.andThen(stow);
Function<Integer,Wrap<String>> itow2 = stow.compose(itos);
System.out.println(itow.apply(3));
System.out.println(itow2.apply(3));
}
In den obigen code, wie erwartet, die 2 Funktionen itow
und itow2
zu sein scheinen gleichwertig. Aber sind Sie tatsächlich gleichwertig? Tun die das gleiche Ergebnis eher durch Zufall in diesem Fall?
Der Gedanke kommt, dass beide compose
und andThen
Methoden existieren für einen Grund, und, dass die Funktionen oder BiFunctions vielleicht nicht immer reversibel sein, auf diese Weise. Können Sie denken, von den Fällen, in denen die Umkehrung nicht gelten würden?
- Weiter dachte, ich lief in die Verwirrung mit BiFunction, und natürlich haben Sie nicht compose () - aus offensichtlichen Gründen. Sieht aus wie Funktionen eigentlich nicht brauchen, compose () - überhaupt, dann() ist viel intuitiver IMO.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Während
a.andThen(b)
entsprichtb.compose(a)
gibt es einen praktischen Unterschied bei der Verwendung von Website, wenn nur eine dieser beiden Funktionen wird ein bereits vorhandener Funktionen.Nehme an, Sie haben die bereits bestehende Funktion
und dann wollen Sie an die Kette einer Zeichenketten-transformation, z.B.
andThen
offensichtlich ist viel bequemer, im Vergleich zuAuf der anderen Seite, wenn Sie Ihre bereits vorhandenen Funktion ist
und Sie möchten, erstellen Sie die angegebenen hex-Funktion,
viel bequemer als
Also die Entscheidung für eine Methode hängt davon ab, welche Funktion bereits vorhanden ist. Wenn die beiden bereits vorhandenen Funktionen, es spielt keine Rolle, welche Methode Sie verwenden (es sei denn, Sie vermuten, dass eine dieser Funktionen möglicherweise überschrieben haben, diese Methoden durchzuführen, eine effizientere Zusammensetzung). Wenn Sie keine bestehende Funktion als Startpunkt, es gibt keinen Grund, eine der folgenden Methoden verwenden, wie Sie können, schreiben die komponierte Ausdruck als ein einzelnes lambda-Ausdruck.
Sind Sie gleichwertig.
Oder in anderen Worten:
x.andThen(y)
ist das gleiche wiey.compose(x)
.Den source-code für
Function
ist frei verfügbar:Aus diesem Grund ist es ziemlich klar, dass
a.andThen(b)
entsprichtb.compose(a)
.Es ist vielleicht sogar noch deutlicher, wenn wir das stillschweigend
this
explicit:Können Sie Fragen, wenn Sie gleichbedeutend sind, warum nicht beides existieren?
Gut, Sie sind nur da als Bequemlichkeit an Erster Stelle. Sie verwalten könnte, ohne entweder von Ihnen:
... ist natürlich äquivalent zu:
So, da Sie es als eine Bequemlichkeit, die jeweils bequem in den verschiedenen Umständen. Sie können wählen, welche ist besonders ausdrucksstark in einer bestimmten situation.
Aus den Javadocs, es gibt einen klaren Unterschied zwischen
compose
undandThen
:Als solche, die Reversibilität wird, hängt von der Implementierung der Funktion.
In deinem Fall
itow
unditow2
sind nur zwei alternative Ausdrucksmöglichkeiten des gleichen: "runitos
, dannstow
in dieser Reihenfolge".Ich würde sagen, dass Sie gleichwertig sind, sehen die Umsetzung:
x.compose(y)
=x.apply(y.apply(...))
und
y.andThen(x)
=x.apply(y.apply(...))
Vom
Function.java
(ich Hinzugefügtthis.
für die Klarheit):folgende Beispiel zeigt, dass
andThen()
&compose()
sind widersprüchlich Methoden. Ihr produziert Gegenteil zu einander.(siehe die Ausgabe für mehr Klarheit)f1.andThen(f2).apply(10);
=> zuerst ausführenf1.apply(10)
Methode. basierend auf der Ausgabe der ersten Methodef2.apply(result_of_f1_method)
Methode execute.f1.compose(f2).apply(10);
=> hier nur gegenüberandThen()
Methode.erste
f2.apply()
und dannf1.apply(output_of_f2_method)
ausführen.Beide sind ähnlich, außer der Folge, wie er führt die Funktionen, siehe Beispiel unten-
AUSGABE