Ich habe das bevorstehende überprüft Java update
, nämlich : Java 8 or JDK 8
. Ja, ich bin ungeduldig, es gibt viele neue Dinge, aber es gibt etwas, das ich nicht verstehe, einen einfachen Code:
final Stream<Integer>stream = Stream.of(1,2,3,4,5,6,7,8,9,10);
stream.flatMap();
Die Javadocs sind
public <R> Stream<R> flatMap(Function<? super T,? extends Stream<? extends R>> mapper)
Gibt einen Stream zurück, der aus den Ergebnissen des Ersetzens jedes Elements dieses Streams durch den Inhalt eines zugeordneten Streams besteht, der durch Anwenden der bereitgestellten Zuordnungsfunktion auf jedes Element erstellt wurde. Jeder zugeordnete Stream wird geschlossen, nachdem sein Inhalt in diesen Stream eingefügt wurde. (Wenn ein zugeordneter Stream null ist, wird stattdessen ein leerer Stream verwendet.) Dies ist eine Zwischenoperation.
Ich würde mich freuen, wenn jemand einige einfache Beispiele flatMap
aus der Praxis erstellen würde, wie Sie es in früheren Java-Versionen Java[6,7]
codieren können und wie Sie dieselben Routinen mit codieren können Java 8
.
quelle
Antworten:
Für
flatMap
einen Stream , der bereits flach ist, wie den, macht es keinen SinnStream<Integer>
Sie in Ihrer Frage gezeigt haben, ist .Wenn Sie jedoch ein
Stream<List<Integer>>
Dann hätten, wäre es sinnvoll und Sie könnten dies tun:Welches würde drucken:
Um dies vor Java 8 zu tun, benötigen Sie nur eine Schleife:
quelle
Beispiel erfunden
Stellen Sie sich vor, Sie möchten die folgende Sequenz erstellen: 1, 2, 2, 3, 3, 3, 4, 4, 4, 4 usw. (mit anderen Worten: 1x1, 2x2, 3x3 usw.)
Damit
flatMap
könnte es aussehen wie:wo:
IntStream.rangeClosed(1, 4)
Erstellt einen Streamint
von 1 bis einschließlich 4IntStream.iterate(i, identity()).limit(i)
erstellt einen Stream der Länge i vonint
i - soi = 4
wird ein Stream erstellt, der darauf angewendet wird:4, 4, 4, 4
flatMap
"glättet" den Stream und "verkettet" ihn mit dem ursprünglichen StreamMit Java <8 benötigen Sie zwei verschachtelte Schleifen:
Beispiel aus der realen Welt
Nehmen wir an, ich habe eine,
List<TimeSeries>
bei der jedeTimeSeries
im Wesentlichen eine istMap<LocalDate, Double>
. Ich möchte eine Liste aller Daten erhalten, für die mindestens eine der Zeitreihen einen Wert hat.flatMap
zur Rettung:Es ist nicht nur lesbar, sondern wenn Sie plötzlich 100.000 Elemente verarbeiten müssen,
parallel()
verbessert das einfache Hinzufügen die Leistung, ohne dass Sie gleichzeitig Code schreiben müssen.quelle
Function.identity
.import static java.util.function.Function.identity;
Extrahieren Sie eindeutige ASC-sortierte Wörter aus einer Liste von Phrasen:
... und die Ausgabe:
quelle
Bin ich der einzige, der Abwicklungslisten langweilig findet? ;-);
Versuchen wir es mit Objekten. Beispiel aus der realen Welt übrigens.
Gegeben: Objekt, das sich wiederholende Aufgaben darstellt. Zu wichtigen Aufgabenfeldern: Erinnerungen beginnen zu klingeln
start
und wiederholen sich allerepeatPeriod
repeatUnit
(z. B. 5 STUNDEN) und es werdenrepeatCount
insgesamt Erinnerungen angezeigt (einschließlich des Startens einer).Ziel: Erstellen Sie eine Liste mit Aufgabenkopien, eine für jeden Aufruf der Aufgabenerinnerung.
Ausgabe:
PS: Ich würde mich freuen, wenn jemand eine einfachere Lösung vorschlagen würde, ich bin doch kein Profi.
UPDATE: @RBz hat um detaillierte Erklärung gebeten, also hier ist es. Grundsätzlich fügt flatMap alle Elemente aus Streams in einem anderen Stream in den Ausgabestream ein. Viele Streams hier :). Daher
x -> LongStream.iterate...
erstellt der Lambda-Ausdruck für jede Aufgabe im anfänglichen Stream einen Stream mit langen Werten, die die Startmomente der Task darstellen. Dieser Stream ist aufx.getRepeatCount()
Instanzen beschränkt . Die Werte beginnen beix.getStart().toEpochSecond(ZoneOffset.UTC)
und jeder nächste Wert wird mit Lambda berechnetp -> (p + x.getRepeatPeriod()*x.getRepeatUnit().getDuration().getSeconds()
.boxed()
Gibt den Stream mit jedem langen Wert als Long-Wrapper-Instanz zurück. Dann wird jedes Long in diesem Stream einer neuen Task-Instanz zugeordnet, die sich nicht mehr wiederholt und die genaue Ausführungszeit enthält. Dieses Beispiel enthält nur eine Aufgabe in der Eingabeliste. Aber stell dir vor, du hast tausend. Sie haben dann einen Stream von 1000 Streams von Task-Objekten. Und wasflatMap
Hier werden alle Aufgaben aus allen Streams auf denselben Ausgabestream übertragen. Das ist alles so wie ich es verstehe. Danke, für ihre Frage!quelle
Am I the only one who finds unwinding lists boring?
+1Diese Methode verwendet eine Funktion als Argument, diese Funktion akzeptiert einen Parameter T als Eingabeargument und gibt einen Strom von Parameter R als Rückgabewert zurück. Wenn diese Funktion auf jedes Element dieses Streams angewendet wird, wird ein Stream mit neuen Werten erstellt. Alle Elemente dieser neuen Streams, die von jedem Element generiert werden, werden dann in einen neuen Stream kopiert, der ein Rückgabewert dieser Methode ist.
http://codedestine.com/java-8-stream-flatmap-method/
quelle
Ein sehr einfaches Beispiel: Teilen Sie eine Liste mit vollständigen Namen, um eine Liste mit Namen zu erhalten, unabhängig vom ersten oder letzten
Dies druckt aus:
quelle
Angesichts dessen:
und das:
Wir können dann folgendes tun:
quelle