Java 8 Streams peek () API

1. Einleitung

Die Java Stream API führt uns in eine leistungsstarke Alternative zur Datenverarbeitung ein.

In diesem kurzen Tutorial konzentrieren wir uns auf peek () , eine oft missverstandene Methode.

2. Kurzes Beispiel

Lassen Sie uns unsere Hände schmutzig machen und versuchen, peek () zu verwenden . Wir haben einen Strom von Namen, und wir möchten sie auf der Konsole drucken.

Da peek () einen Verbraucher als einziges Argument erwartet , scheint es gut zu passen. Probieren wir es also aus:

Stream nameStream = Stream.of("Alice", "Bob", "Chuck"); nameStream.peek(System.out::println);

Das obige Snippet erzeugt jedoch keine Ausgabe. Um zu verstehen, warum, lassen Sie uns eine kurze Auffrischung der Aspekte des Stream-Lebenszyklus durchführen.

3. Zwischen- und Terminalbetrieb

Denken Sie daran, dass Streams aus drei Teilen bestehen: einer Datenquelle, null oder mehr Zwischenoperationen und null oder einer Terminaloperation.

Die Quelle stellt die Elemente für die Pipeline bereit.

Zwischenoperationen rufen Elemente einzeln ab und verarbeiten sie. Alle Zwischenoperationen sind faul und daher haben keine Operationen Auswirkungen, bis die Pipeline zu arbeiten beginnt.

Terminaloperationen bedeuten das Ende des Stream-Lebenszyklus. Am wichtigsten für unser Szenario ist, dass sie die Arbeit in der Pipeline einleiten .

4. peek () Verwendung

Der Grund peek () nicht in unserem ersten Beispiel arbeitete , ist , dass es eine ist Zwischen Betrieb und wir haben keine Anwendung Terminalbetrieb an die Pipeline. Alternativ hätten wir forEach () mit demselben Argument verwenden können, um das gewünschte Verhalten zu erhalten:

Stream nameStream = Stream.of("Alice", "Bob", "Chuck"); nameStream.forEach(System.out::println);

Auf der Javadoc-Seite von peek () heißt es: „ Diese Methode unterstützt hauptsächlich das Debuggen, bei dem Sie die Elemente sehen möchten, wenn sie an einem bestimmten Punkt in einer Pipeline vorbeifließen .“

Betrachten wir diesen Ausschnitt aus derselben Javadoc-Seite:

Stream.of("one", "two", "three", "four") .filter(e -> e.length() > 3) .peek(e -> System.out.println("Filtered value: " + e)) .map(String::toUpperCase) .peek(e -> System.out.println("Mapped value: " + e)) .collect(Collectors.toList());

Es zeigt, wie wir die Elemente beobachten, die jede Operation bestanden haben.

Darüber hinaus kann peek () in einem anderen Szenario nützlich sein: Wenn wir den inneren Zustand eines Elements ändern möchten . Angenommen, wir möchten den Namen aller Benutzer vor dem Drucken in Kleinbuchstaben konvertieren:

Stream userStream = Stream.of(new User("Alice"), new User("Bob"), new User("Chuck")); userStream.peek(u -> u.setName(u.getName().toLowerCase())) .forEach(System.out::println);

Alternativ hätten wir map () verwenden können , aber peek () ist praktischer, da wir das Element nicht ersetzen möchten.

5. Schlussfolgerung

In diesem kurzen Tutorial haben wir eine Zusammenfassung des Stream-Lebenszyklus gesehen, um zu verstehen, wie peek () funktioniert. Wir haben auch zwei alltägliche Anwendungsfälle gesehen, bei denen die Verwendung von peek () die einfachste Option ist.

Und wie immer sind die Beispiele auf GitHub verfügbar.