Ich habe in java8 keinen Code in diesem Bereich geschrieben, daher habe ich ein Gefühl der Krise verspürt und ihn gelernt. Deshalb werde ich ihn hier zusammenfassen.
Dies ist ein Beispiel, das den Inhalt der Liste in Zahlen umwandelt und ausgibt. Zunächst ein Beispiel vor java8.
Nicht java8.java
List<String> suuzies = Arrays.asList("1", "2", null, "3");
for (String suuzi : suuzies) {
if (suuzi == null) {
continue;
}
System.out.println(Integer.parseInt(suuzi));
}
// 1 2 3
Als nächstes kommt Java8.
java8.java
List<String> suuzies = Arrays.asList("1", "2", null, "3");
suuzies.stream().filter(s -> Objects.nonNull(s)).map(s -> Integer.parseInt(s))
.forEach(s -> System.out.println(s));
// 1 2 3
Toll! Es passt in eine Zeile und verbessert die Lesbarkeit! Als ich es zum ersten Mal sah, verstand ich es überhaupt nicht und dachte, was die Lesbarkeit verbessern würde. Es wird erfrischend zu verstehen sein.
Die Reihenfolge der Stream-Verarbeitung
In Anbetracht dessen, dass Sie den Prozess so schreiben können, als ob er wie oben beschrieben durch einen Pfeil verbunden wäre, Ich bin sicher der Meinung, dass sich die Lesbarkeit verbessert hat. Wenn auf Feldebene das Nest oft chaotisch wird, Dies scheint sehr leicht zu lesen zu sein.
Der java8.java-Code kann übrigens auch wie folgt geschrieben werden.
java8(2).java
List<String> suuzies = Arrays.asList("1", "2", null, "3");
suuzies.stream().filter(Objects::nonNull).map(Integer::parseInt)
.forEach(System.out::println);
// 1 2 3
Es werden Methodenreferenzen verwendet, wodurch der Code noch kürzer wird. Ich werde die Erklärung hier weglassen.
Nachdem Sie Stream verstanden haben, werde ich ein wenig über Lambda-Ausdrücke schreiben.
Stream.class
Stream<T> filter(Predicate<? super T> predicate);
Predicate.class
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
default Predicate<T> negate() {
return (t) -> !test(t);
}
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
}
Die oben gezeigte Filtermethode sieht beispielsweise so aus. Ich war allergisch, als ich es zum ersten Mal sah. Es schloss sofort. Schauen wir uns auch (Prädikat <? Super T>) im Argument des Filters an. Dies ist eine funktionale Schnittstelle. Ein Lambda-Ausdruck kann eine funktionale Schnittstelle mit einer kurzen Beschreibung implementieren. Eine funktionale Schnittstelle ist übrigens eine, in der nur eine abstrakte Methode definiert ist. Es ist in Ordnung, andere statische und Standardmethoden als abstrakte Methoden einzuschließen, diese werden jedoch als Bedingung ignoriert. Die Prädikatklasse zielt nur auf den "Booleschen Test (T t)" ab, die anderen werden ignoriert.
Wie Sie sehen können, verwendet diese Schnittstelle ein Argument vom Typ T und gibt einen Rückgabewert vom Typ Boolean zurück. Wiederholen Sie den Filterteil des vorherigen Codes (java8.java).
java8.java
filter(s -> Objects.nonNull(s))
Es implementiert das Filterargument von Stream.class. Dieser Teil ist ein Lambda-Typ!
Es stehen mehrere andere Funktionsschnittstellen zur Verfügung. Mit der in java8.class verwendeten Karte
Stream.class
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
Schauen wir uns auch den Inhalt des Arguments Function an.
Function.class
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
// and more
}
Eine Methode, die einen T-Typ als Argument verwendet und einen R-Typ zurückgibt! Mit anderen Worten, es verarbeitet das empfangene Argument und gibt es in einer anderen Form zurück!
Wiederholen Sie den Kartenteil von java8.java früher.
java8.java
map(s -> Integer.parseInt(s))
Sie nehmen ein Zeichen als Argument, konvertieren es in eine Zahl und geben es zurück!
Die Lambda-Ausdruckssyntax sieht folgendermaßen aus.
(Argument) -> {Verarbeitung}
Es ist eine Schreibweise, weil es nur eine abstrakte Methode gibt ♪ Es gibt andere Verbraucher, die keinen Rückgabewert haben, und Lieferanten, die keine Argumente annehmen!
Ich denke, der Lambda-Ausdruck wurde für Stream gemacht! Zu Beginn des Studiums frage ich mich, ob es eine Schnittstelle für eine abstrakte Methode gibt. Ich dachte, aber wir Entwickler werden die vorbereiteten Dinge in einem Lambda-Stil implementieren Ich dachte, es wäre praktisch, wenn ich es benutzen würde!
Ich habe noch viel zu tun, deshalb werde ich von nun an mein Verständnis vertiefen!
Recommended Posts