Ich versuche, einige for-each-Schleifen in Lambda- forEach()
Methoden zu ändern, um die Möglichkeiten von Lambda-Ausdrücken zu entdecken. Folgendes scheint möglich zu sein:
ArrayList<Player> playersOfTeam = new ArrayList<Player>();
for (Player player : players) {
if (player.getTeam().equals(teamName)) {
playersOfTeam.add(player);
}
}
Mit Lambda forEach()
players.forEach(player->{if (player.getTeam().equals(teamName)) {playersOfTeam.add(player);}});
Aber der nächste funktioniert nicht:
for (Player player : players) {
if (player.getName().contains(name)) {
return player;
}
}
mit Lambda
players.forEach(player->{if (player.getName().contains(name)) {return player;}});
Stimmt etwas in der Syntax der letzten Zeile nicht oder ist es unmöglich, von der forEach()
Methode zurückzukehren?
return
innerhalb einer Aussage kehrt Lambda vom Lambda selbst zurück, nicht von dem, was Lambda genannt wird. Sie beenden einen Stream vorzeitig ("Kurzschluss"),findFirst
wie in der Antwort von Ian Roberts gezeigt .Antworten:
Das
return
dort kehrt eher vom Lambda-Ausdruck als von der enthaltenden Methode zurück. Stattdessen müssenforEach
Sie zumfilter
Stream:Hier
filter
beschränkt sich der Stream auf die Elemente, die mit dem Prädikat übereinstimmen, und gibtfindFirst
dann einenOptional
mit dem ersten übereinstimmenden Eintrag zurück.Dies sieht weniger effizient aus als der For-Loop-Ansatz,
findFirst()
kann jedoch einen Kurzschluss verursachen. Es wird nicht der gesamte gefilterte Stream generiert und dann ein Element daraus extrahiert, sondern es werden nur so viele Elemente gefiltert, wie erforderlich sind finde den ersten passenden. Sie können auch verwenden,findAny()
anstatt,findFirst()
wenn Sie nicht unbedingt den ersten passenden Spieler aus dem (bestellten) Stream erhalten möchten, sondern einfach einen passenden Gegenstand. Dies ermöglicht eine bessere Effizienz bei Parallelität.quelle
orElse(null)
auf einem verwendenOptional
. Der Hauptpunkt vonOptional
besteht darin, eine Möglichkeit bereitzustellen, das Vorhandensein oder Fehlen eines Werts anzuzeigen, anstatt Null zu überladen (was zu NPEs führt). Wenn Sie es verwendenoptional.orElse(null)
, werden alle Probleme mit Nullen zurückgekauft. Ich würde es nur verwenden, wenn Sie den Anrufer nicht ändern können und er wirklich eine Null erwartet.Optional<Player>
eine natürlichere Möglichkeit, sich in das Streams-Paradigma einzufügen . Ich habe nur versucht zu zeigen, wie man das vorhandene Verhalten mit Lambdas dupliziert.Ich empfehle Ihnen, zunächst zu versuchen, Java 8 im gesamten Bild zu verstehen. In Ihrem Fall handelt es sich vor allem um Streams, Lambdas und Methodenreferenzen.
Sie sollten vorhandenen Code niemals zeilenweise in Java 8-Code konvertieren. Sie sollten Funktionen extrahieren und diese konvertieren.
Was ich in Ihrem ersten Fall identifiziert habe, ist Folgendes:
Mal sehen, wie wir das machen, wir können es mit folgendem machen:
Was Sie hier tun, ist:
Collection<Player>
, jetzt haben Sie einenStream<Player>
.Predicate<Player>
und ordnen Sie jeden Spieler dem booleschen Wert true zu, wenn er beibehalten werden soll.Collector
, hier können wir einen der Standardbibliothekssammler verwenden, nämlichCollectors.toList()
.Dies beinhaltet auch zwei weitere Punkte:
List<E>
OverArrayList<E>
.new ArrayList<>()
, Sie verwenden schließlich Java 8.Nun zu Ihrem zweiten Punkt:
Sie möchten wieder etwas von altem Java in Java 8 konvertieren, ohne das Gesamtbild zu betrachten. Dieser Teil wurde bereits von @IanRoberts beantwortet , obwohl ich denke, dass Sie
players.stream().filter(...)...
über das hinausgehen müssen, was er vorgeschlagen hat.quelle
Wenn Sie einen booleschen Wert zurückgeben möchten, können Sie Folgendes verwenden (viel schneller als Filter):
quelle
Das hat mir geholfen:
Entnommen aus Java 8 Finden eines bestimmten Elements in einer Liste mit Lambda
quelle
Sie können auch eine Ausnahme auslösen:
Hinweis:
Aus Gründen der Lesbarkeit sollte jeder Stream-Schritt in einer neuen Zeile aufgeführt werden.
Wenn Ihre Logik lose "ausnahmegesteuert" ist, z. B. gibt es eine Stelle in Ihrem Code, die alle Ausnahmen abfängt und entscheidet, was als nächstes zu tun ist. Verwenden Sie eine ausnahmegesteuerte Entwicklung nur, wenn Sie vermeiden können, dass Ihre Codebasis mit Vielfachen
try-catch
übersät ist und diese Ausnahmen für ganz besondere Fälle ausgelöst werden, in denen Sie sie erwarten und die ordnungsgemäß behandelt werden können.)quelle