Was sind Javas Äquivalente von Func und Action ?
Ich meine, anstatt dies selbst zu schreiben:
public interface Func<TInput, TResult>
{
TResult call(TInput target) throws Exception;
}
public interface Action<T>
{
void call(T target) throws Exception;
}
Antworten:
In Java 8 sind die Äquivalente der
java.util.function.Function<T, R>
undjava.util.function.Consumer<T>
Schnittstellen sind. Ebensojava.util.function.Predicate<T>
ist äquivalent zuSystem.Predicate<T>
. Wie an anderer Stelle erwähnt, handelt es sich hierbei um Schnittstellen anstelle von Delegaten.Nebenbei bemerkt: Ich stütze mich derzeit stark auf die folgende Utility-Klasse, um LINQ-ähnliche Erweiterungsmethoden zu erstellen:
Im Gegensatz zu
System.Linq.Enumerable.Where<TSource>
undSystem.Linq.Enumerable.Select<TSource, TResult>
den LINQ-ähnlichen Methoden, die ich hier vorstelle, sind sie nicht faul und durchlaufen die Quellensammlungen vollständig, bevor die Ergebnissammlungen an den Aufrufer zurückgegeben werden. Trotzdem finde ich sie für rein syntaktische Zwecke nützlich und könnte bei Bedarf faul gemacht werden. GegebenMan kann folgendes tun:
Was ich dem folgenden vorziehe:
quelle
Function<T, R>
undConsumer<T>
können Sie den vollen Satz von gemeinsamen funktionalen Schnittstellen finden , dass Java bietet hier .Abrufbar Schnittstelle ähnelt Func.
Runnable Schnittstelle ähnelt der Aktion.
Im Allgemeinen verwendet Java anonyme innere Klassen als Ersatz für C # -Delegierte. So fügen Sie beispielsweise Code hinzu, um auf das Drücken von Tasten in der GUI zu reagieren:
quelle
Die Eleganz der überladenen Func Delegierten (neben den Delegierten gegen anonyme Klasse Ausgabe) ist , dass sie 0-16 Argumente unterstützen (
Func<TResult>
,Func<T, TResult>
,Func<T1, T2, TResult>
, etc.)Leider ist dies in Java aufgrund der Typlöschung nicht möglich. Klassen können sich nicht allein durch generische Typparameter unterscheiden.
Java 8 bringt jetzt einen Zoo mit Namen wie
BiConsumer
fürAction<T, T2>
und, da Java keine primitiven Typargumente zulässtBiIntConsumer
. Der "Zoo" ist jedoch nicht sehr groß, und mir ist keine Bibliothek bekannt, die ihn erweitert. Es gab einen wunderbaren Vorschlag für Literale vom Funktionstyp wie,(int, int) => void
aber er wurde nicht angenommen.quelle
Func`1
usw. Es ist nur C #, das diese dem gleichen Namen zuordnet.BiConsumer
fürAction<T, T2>
und, da Java keine primitiven Typparameter zulässtBiIntConsumer
. Es gab einen Vorschlag für Funktionstyp-Literale wie, der(int, int) => void
jedoch nicht angenommen wurde.Zur
Func<T>
Verwendung: java.util.function.Supplier http://docs.oracle.com/javase/8/docs/api/java/util/function/Supplier.htmlquelle
Supplier
wäre gleichbedeutend mitFunc<T>
(im Gegensatz zuFunc<T1, T2>
) nichtAction
. AnAction
akzeptiert keine Argumente und gibt kein Ergebnis zurück. (Andere Versionen vonAction
akzeptieren verschiedene Anzahlen von Argumenten und geben kein Ergebnis zurück.)Func<T>
Java gesucht habe und mich fälschlicherweise daran erinnert habeAction<T>
. OopsAction<>
: 0 Eingänge, 0 Ausgänge. Bestenfalls mit.andThen(...)
Funktionalität.Action<>
und mit 0 Eingaben und 0 Ausgaben vergleichbar ist. Aber denken Sie daran, in Java sind dies nur Schnittstellen. So können Sie Ihre eigenen erstellen, um sie zu verwenden.Runnable
fürAction<>
, obwohl es nicht ganz so hübsch zu bedienen ist wie das neue Java 8-Funktionsmaterial.Es gibt wirklich keine Entsprechungen für diese. Sie können in Java anonyme innere Klassen erstellen, es gibt jedoch eher bestimmte Schnittstellen als generische wie Func und Action.
quelle
Java hat nicht das Konzept von Delegierten. Eine Problemumgehung finden Sie unter Ein Java-Programmierer betrachtet C # -Delegierte :
quelle
Sie können java.util.Function wie folgt verwenden
Wenn Sie es jedoch mit mehr als einem Argument verwenden möchten (wie es C # Func tut), müssen Sie Ihre Version von FunctionalInterface wie folgt definieren
Dann können Sie mit der Variablen Anzahl der Argumente verwenden
quelle
Für ältere Versionen als Java 8
Für Methodenrückrufe in C #, die ich wie folgt verwendet habe:
und nenne es:
Ich habe kleine abstrakte Klassen in Java gemacht
Die Java-Methode sieht folgendermaßen aus:
Wenn Sie es jetzt in Java aufrufen:
Dies funktioniert auch, indem Sie Ihre Rückrufe an die Klassen übergeben / festlegen, in denen Sie sie aufrufen möchten. Dieselbe Methode kann auch zum Erstellen von Schnittstellen verwendet werden:
quelle