Java Stream Filter mit Lambda-Ausdruck

1. Einleitung

In diesem kurzen Tutorial werden wir die Verwendung der Stream.filter () -Methode untersuchen, wenn wir mit Streams in Java arbeiten.

Wir werden uns ansehen, wie man es benutzt und wie man Sonderfälle mit aktivierten Ausnahmen behandelt.

2. Verwenden von Stream.filter ()

Die filter () -Methode ist eine Zwischenoperation der Stream- Schnittstelle, mit der wir Elemente eines Streams filtern können, die einem bestimmten Prädikat entsprechen:

Stream filter(Predicate predicate)

Um zu sehen, wie dies funktioniert, erstellen wir eine Kundenklasse :

public class Customer { private String name; private int points; //Constructor and standard getters }

Lassen Sie uns außerdem eine Sammlung von Kunden erstellen:

Customer john = new Customer("John P.", 15); Customer sarah = new Customer("Sarah M.", 200); Customer charles = new Customer("Charles B.", 150); Customer mary = new Customer("Mary T.", 1); List customers = Arrays.asList(john, sarah, charles, mary);

2.1. Sammlungen filtern

Ein häufiger Anwendungsfall der filter () -Methode ist die Verarbeitung von Sammlungen.

Lassen Sie uns eine Kundenliste mit mehr als 100 Punkten erstellen. Dazu können wir einen Lambda-Ausdruck verwenden:

List customersWithMoreThan100Points = customers .stream() .filter(c -> c.getPoints() > 100) .collect(Collectors.toList());

Wir können auch eine Methodenreferenz verwenden, die für einen Lambda-Ausdruck eine Abkürzung ist:

List customersWithMoreThan100Points = customers .stream() .filter(Customer::hasOverHundredPoints) .collect(Collectors.toList());

In diesem Fall haben wir die hasOverHundredPoints Methode zu unserer Kundenklasse:

public boolean hasOverHundredPoints() { return this.points > 100; }

In beiden Fällen erhalten wir das gleiche Ergebnis:

assertThat(customersWithMoreThan100Points).hasSize(2); assertThat(customersWithMoreThan100Points).contains(sarah, charles);

2.2. Filtern von Sammlungen mit mehreren Kriterien

Darüber hinaus können wir mit filter () mehrere Bedingungen verwenden . Zum Beispiel können wir nach Punkten und Namen filtern :

List charlesWithMoreThan100Points = customers .stream() .filter(c -> c.getPoints() > 100 && c.getName().startsWith("Charles")) .collect(Collectors.toList()); assertThat(charlesWithMoreThan100Points).hasSize(1); assertThat(charlesWithMoreThan100Points).contains(charles);

3. Umgang mit Ausnahmen

Bisher haben wir den Filter mit Prädikaten verwendet, die keine Ausnahme auslösen. In der Tat deklarieren die Funktionsschnittstellen in Java keine aktivierten oder nicht aktivierten Ausnahmen .

Als nächstes zeigen wir verschiedene Möglichkeiten, um Ausnahmen in Lambda-Ausdrücken zu behandeln.

3.1. Verwenden eines benutzerdefinierten Wrappers

Zunächst fügen wir unserem Kunden ein profilePhotoUrl hinzu :

private String profilePhotoUrl;

Fügen Sie außerdem eine einfache hasValidProfilePhoto () -Methode hinzu, um die Verfügbarkeit des Profils zu überprüfen:

public boolean hasValidProfilePhoto() throws IOException { URL url = new URL(this.profilePhotoUrl); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); return connection.getResponseCode() == HttpURLConnection.HTTP_OK; }

Wir können sehen, dass die Methode hasValidProfilePhoto () eine IOException auslöst . Wenn wir nun versuchen, die Kunden mit dieser Methode zu filtern:

List customersWithValidProfilePhoto = customers .stream() .filter(Customer::hasValidProfilePhoto) .collect(Collectors.toList());

Wir werden den folgenden Fehler sehen:

Incompatible thrown types java.io.IOException in functional expression

Eine der Alternativen, die wir verwenden können, ist das Umschließen mit einem Try-Catch-Block:

List customersWithValidProfilePhoto = customers .stream() .filter(c -> { try { return c.hasValidProfilePhoto(); } catch (IOException e) { //handle exception } return false; }) .collect(Collectors.toList());

Wenn wir eine Ausnahme von unserem Prädikat auslösen müssen , können wir sie in eine ungeprüfte Ausnahme wie RuntimeException einschließen .

3.2. Verwenden der ThrowingFunction

Alternativ können wir die ThrowingFunction-Bibliothek verwenden.

ThrowingFunction ist eine Open Source-Bibliothek, mit der wir geprüfte Ausnahmen in Java-Funktionsschnittstellen behandeln können.

Beginnen wir mit dem Hinzufügen der Abhängigkeit von der Wurffunktion zu unserem POM:

 pl.touk throwing-function 1.3 

Um Ausnahmen in Prädikaten zu behandeln, bietet uns diese Bibliothek die ThrowingPredicate- Klasse an, die über die Methode unchecked () verfügt , um geprüfte Ausnahmen zu verpacken.

Lassen Sie es uns in Aktion sehen:

List customersWithValidProfilePhoto = customers .stream() .filter(ThrowingPredicate.unchecked(Customer::hasValidProfilePhoto)) .collect(Collectors.toList());

4. Fazit

In diesem Artikel haben wir ein Beispiel für die Verwendung der filter () -Methode zum Verarbeiten von Streams gesehen. Wir haben auch einige Alternativen untersucht, um Ausnahmen zu behandeln.

Wie immer ist der vollständige Code auf GitHub verfügbar.