Es ist lange her seit der Veröffentlichung von Java8, aber ich habe aus irgendeinem Grund Lambda-Ausdrücke und die Stream-API verwendet, daher werde ich es noch einmal zusammenfassen.
Lambda-Ausdrücke sind eine einfache Möglichkeit, eine Schnittstelle mit nur einer Methode zu implementieren, die als funktionale Schnittstelle bezeichnet wird.
In einer funktionalen Sprache wie lisp oder einer Sprache wie C mit einem Funktionszeiger können Sie leicht eine "Funktion" übergeben, in Java können Sie sie jedoch nur übergeben, wenn die Funktion ein Objekt ist. Durch Vorbereiten einer Funktionsschnittstelle wie der folgenden ist es daher möglich, eine Funktion zu übergeben.
Func.java
package jp.foo;
public interface Func {
public double apply(double x);
}
Eine funktionale Schnittstelle hat nur eine abstrakte Methode.
Bis java7 wurde die abstrakte Methode wie folgt überschrieben.
Func g = new Func(){
@Override
public double apply(double x) {
return x * x;
}
};
In Java8 kann die Beschreibung wie folgt vereinfacht werden, indem die Tatsache ausgenutzt wird, dass die Funktionsschnittstelle nur eine Methode hat. Dies ist der Lambda-Ausdruck.
Func f = x -> x * x;
Wenn Sie etwas enger schreiben
Func f = (x) -> {return x * x;};
Im Allgemeinen wird es beschrieben als "(Argument 1, Argument 2, ...) -> {Prozess 1; Prozess 2; ...}".
Wenn es kein Argument oder keine Rückgabe gibt, können Sie es natürlich leer schreiben wie () -> {}
.
Dies überschreibt nur eine Methode der Funktionsschnittstelle.
Die Funktionsschnittstelle vereinfacht die Beschreibung, indem sie die Tatsache ausnutzt, dass nur eine Methode überschrieben werden kann.
Dieser Lambda-Ausdruck ist beispielsweise nützlich, wenn eine Methode verwendet wird, die eine funktionale Schnittstelle als Argument verwendet (z. B. wie unten gezeigt).
FuncUser.java
package jp.foo;
public class FuncUser {
public static void samplePrintFunc(Func f) {
for(double x = 1.0; x <= 3.0; x += 1.0) {
System.out.println(f.apply(x));
}
}
}
Die einfache Beschreibung lautet wie folgt.
FuncUser.samplePrintFunc(x -> x * x);
FuncUser.samplePrintFunc(x -> Math.sin(x));
Wenn der Prozess etwas kompliziert wird, können Sie mehrere Prozesse beschreiben, indem Sie sie in "{// mehrere Prozesse beschreiben}" einfügen.
FuncUser.samplePrintFunc(x -> { a = Math.sin(x); b = Math.cos(x); return a * b; });
Wenn es nur einen Prozess gibt und der Argumenttyp der Funktionsschnittstelle und der Argumenttyp der Methode, die Sie verwenden möchten, identisch sind, können Sie ihn wie folgt weglassen.
FuncUser.samplePrintFunc(Math::sin);
Lambda-Ausdrücke sind daher eine leistungsfähige Grammatik zum Übergeben von Funktionen.
Stream API
Die Stream-API ist ein Tool, das die Sammlungsverarbeitung mithilfe von Lambda-Ausdrücken wie oben beschrieben ausführt. Es ist eine API im Lambda-Stil. Ich habe diejenigen zusammengefasst, die ich oft als Beispiel verwende.
forEach Es scheint, dass nur forEach verwendet werden kann, ohne die Stream-Methode aufzurufen.
Arrays.asList(new Double[] { 1.0, 2.1, 3.2, 4.3, 5.4 }).forEach(System.out::println);
filter Dies ist praktisch, da eine verfeinerte Suche durchgeführt wird. Es ist einfach, weil Sie nicht in jede for-Anweisung eine if-Anweisung schreiben müssen.
Arrays.asList(new Double[] { 1.0, 2.1, 3.2, 4.3, 5.4 }).stream().filter(x -> x > 3.0).forEach(System.out::println);
map Es wird verwendet, wenn Sie eine andere Liste erstellen und aus einer Liste oder einem Satz festlegen möchten.
Arrays.asList(new Double[] { 1.0, 2.1, 3.2, 4.3, 5.4 }).stream().map(x -> x * x).forEach(System.out::println);
collect sammeln ist mächtig und eliminiert fast das Schreiben für Aussagen.
Schreiben Sie sammeln (Lieferant (außerhalb von for variabel), Akkumulator [innerhalb von for verarbeiten], Kombinierer [Prozess zum Sammeln von Lieferanten zum Zeitpunkt der Parallelverarbeitung]).
Arrays.asList(new Double[] { 1.0, 2.1, 3.2, 4.3, 5.4 }).stream().collect(HashMap::new, (map, x) -> map.put(x, x * x), (map1, map2) -> map1.forEach(map2::put)).entrySet().forEach(System.out::println);
Es ist auch bequem, Collectors zu verwenden. Die Verarbeitung, die Sie häufig durchführen, ist gut abstrahiert und vollständig.
Arrays.asList(new Double[] { 1.0, 2.1, 3.2, 1.0, 5.4 }).stream().collect(Collectors.toSet()).forEach(System.out::println);
mapToDouble etc... Dies ist nützlich, da Sie mithilfe des Streams mapTo [numerischer Wert] Durchschnitt, Maximum und Min verwenden können.
Arrays.asList(new Double[] { 1.0, 2.1, 3.2, 4.3, 5.4 }).stream().mapToDouble(x -> x).average().ifPresent(System.out::println)
Lassen Sie uns die Standardabweichung finden.
\sigma = \sqrt{\frac{1}{n} \sum_{i = 1}^n (x_i - \mu)^2}
Der folgende gewünschte Teil selbst wird mit 2 Zeilen (2. und 3. Zeile) multipliziert.
List<Double> sample = Arrays.asList(new Double[] { 1.0, 2.1, 3.2, 4.3, 5.4 });
double mu = sample.stream().mapToDouble(x -> x).average().getAsDouble();
double siguma = Math.sqrt(sample.stream().map(x -> Math.pow(x - mu, 2.0)).mapToDouble(x -> x).average().getAsDouble());
System.out.println(siguma);
Recommended Posts