Stream-API in Java 8 hinzugefügt. Ich habe nach Bedarf recherchiert und das Minimum verwendet, aber ich habe es nicht gut verstanden, also habe ich es erneut untersucht und ausprobiert.
"Eine Klasse, die funktionale Operationen für einen Strom von Elementen unterstützt". https://docs.oracle.com/javase/jp/8/docs/api/java/util/stream/package-summary.html … Das offizielle Dokument ist schwer zu lesen, wahrscheinlich weil es eine automatische Übersetzung ist. Sie können verstehen, wer Englisch liest ...
Das "Element" hier scheint sich hauptsächlich auf Sammlungselemente wie List zu beziehen. Stream ist genau so, wie es in diesem Artikel geschrieben steht. https://qiita.com/castaneai/items/3dbdd8543b020aa903cb
Meine Interpretation ist
Ich hatte das Gefühl, dass JavaDoc für die Stream-Oberfläche die Basis für alles sein würde, deshalb werde ich mich hier darauf konzentrieren. https://docs.oracle.com/javase/jp/8/docs/api/java/util/stream/Stream.html
Abgeleitete Dinge wie Methoden, die IntStream zurückgeben, werden ausgeschlossen.
Ich habe eine Bean und eine Methode zum Erstellen von Testdaten erstellt. Ich rufe es von der Hauptmethode aus auf, erstelle eine Variable namens list und experimentiere dann.
Bean
public class TestBean {
String key;
String value;
String description;
public TestBean(String key, String value, String description) {
this.setKey(key);
this.setValue(value);
this.setDescription(description);
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Override
public String toString() {
return "key:" + this.key + " value:" + this.value + " description:" + this.description;
}
}
Testdatenerstellungsmethode
private static List<TestBean> editTestData() {
List<TestBean> list = new ArrayList<>();
list.add(new TestBean("B", "Butaman", "Enthält Schweinefleisch"));
list.add(new TestBean("A", "Anman", "Enthält Anko"));
list.add(new TestBean("C", "Chukaman", "Es ist ein allgemeiner Begriff für Anmanbutaman usw."));
return list;
}
filter Wie der Name schon sagt, hat es gefiltert!
filter
list.stream()
.filter(x -> x.getValue().equals("Anman"))
.forEach(x -> System.out.println(x.getDescription()));
Ausführungsergebnis
Enthält Anko
map Ich habe es so interpretiert, dass es einen anderen Stream basierend auf dem Stream erstellt. In diesem Beispiel wird ein Stream vom Typ TestBean durch einen Stream aus String ersetzt.
map
list.stream()
.map(x -> x.getKey() + x.getValue() + x.getDescription())
.forEach(x -> System.out.println(x));
Ausführungsergebnis
B Butaman enthält Schweinefleisch
Ein Anman Anko ist enthalten
C Chukaman Anmanbutaman usw.
flatMap Es scheint, dass Sie einen Stream innerhalb eines Streams erstellen können. Ein Bild wie eine Tabelle mit Stream erstellen? Hier wird jedes Element der Bean, aus dem eine Zeile besteht, getrennt, um einen weiteren Stream zu erstellen.
flatMap
list.stream()
.flatMap(x -> Stream.of(Arrays.asList(x.getKey(),x.getValue(),x.getDescription())))
.forEach(x -> x.forEach(y -> System.out.println(y)));
Ausführungsergebnis
B
Butaman
Enthält Schweinefleisch
A
Anman
Enthält Anko
C
Chukaman
Es ist ein allgemeiner Begriff für Anmanbutaman usw.
distinct Beseitigen Sie doppelte Elemente. Bei der Durchführung dieses Tests haben wir die obigen Testdaten aufgeblasen.
Testdaten (Duplikat a)
private static List<TestBean> editTestData() {
List<TestBean> list = new ArrayList<>();
TestBean a = new TestBean("A", "Anman", "Enthält Anko");
TestBean b = new TestBean("B", "Butaman", "Enthält Schweinefleisch");
TestBean c = new TestBean("C", "Chukaman", "Es ist ein allgemeiner Begriff für Anmanbutaman usw.");
list.add(b);
list.add(a);
list.add(a);
list.add(a);
list.add(c);
return list;
}
Quelle
list.stream()
.forEach(x -> System.out.println(x.getDescription()));
Ausführungsergebnis
Enthält Schweinefleisch
Enthält Anko
Enthält Anko
Enthält Anko
Es ist ein allgemeiner Begriff für Anmanbutaman usw.
Quelle
list.stream()
.distinct()
.forEach(x -> System.out.println(x.getDescription()));
Ausführungsergebnis
Enthält Schweinefleisch
Enthält Anko
Es ist ein allgemeiner Begriff für Anmanbutaman usw.
sorted Sortieren wie der Name schon sagt. In diesem Beispiel werden die Elemente mit dem Namen key (ABC) der Reihe nach sortiert.
sorted
list.stream()
.sorted((o1, o2) -> o1.getKey().compareTo(o2.getKey()))
.forEach(x -> System.out.println(x.getKey() + x.getValue() + x.getDescription()));
Ausführungsergebnis
Ein Anman Anko ist enthalten
B Butaman enthält Schweinefleisch
C Chukaman Anmanbutaman usw.
peek Dies manipuliert den Inhalt des Streams nicht speziell. Es sieht aus wie eine Methode zum Debuggen. peek = Ein Blick (wörtlich übersetzt)
peek
list.stream()
.peek(x -> System.out.println(x))
.forEach(x -> System.out.println("Ausgabe mit forEach"));
Ausführungsergebnis
key:B value:Butaman Beschreibung:Enthält Schweinefleisch
Ausgabe mit forEach
key:A value:Anman Beschreibung:Enthält Anko
Ausgabe mit forEach
key:C value:Chukaman Beschreibung:Es ist ein allgemeiner Begriff für Anmanbutaman usw.
Ausgabe mit forEach
Ich habe mich gefragt, ob forEach durchgeführt werden würde, nachdem alle Peeks zuerst durchgeführt wurden, aber es scheint, dass für jedes Element eine Zwischenverarbeitung → Terminierungsverarbeitung durchgeführt wird.
limit Schneiden Sie die Anzahl der Streams auf die angegebene Anzahl ab.
limit
list.stream()
.limit(2)
.forEach(x -> System.out.println(x));
Ausführungsergebnis
key:B value:Butaman Beschreibung:Enthält Schweinefleisch
key:A value:Anman Beschreibung:Enthält Anko
skip Im Gegensatz zum Limit wird der Beginn des Streams übersprungen.
skip
list.stream()
.skip(1)
.forEach(x -> System.out.println(x));
Ausführungsergebnis
key:A value:Anman Beschreibung:Enthält Anko
key:C value:Chukaman Beschreibung:Es ist ein allgemeiner Begriff für Anmanbutaman usw.
forEach Ich habe es bisher jedes Mal beiläufig benutzt. Verarbeitet alle Elemente von Stream. … Aber es scheint, dass die Bestellung nicht garantiert ist. Nur für parallele Streams?
forEachOrdered Es ist dasselbe wie für jedes, aber es scheint, dass die Bestellung dadurch garantiert wird.
toArray Machen Sie den Stream einfach zu einem Array.
toArray
Object[] testBeans = list.stream().toArray();
System.out.println(testBeans[0].toString());
System.out.println(testBeans[1].toString());
Ausführungsergebnis
key:B value:Butaman Beschreibung:Enthält Schweinefleisch
key:A value:Anman Beschreibung:Enthält Anko
reduce reduzieren = reduzieren, reduzieren (wörtlich) Dies scheint nützlich zu sein, wenn Sie den Inhalt von Stream zusammenfassen. In diesem Beispiel wird das Element mit dem Namen value angehängt. Von Stream wird nur eine Option zurückgegeben. Zusätzlich gibt es eine Reduzierung, die den Anfangswert einstellen kann. Signaturunterschied.
reduce
Optional<TestBean> opt = list.stream()
.reduce((t, u) -> {
t.setValue(t.getValue() + u.getValue());
return t;
});
System.out.println(opt.orElse(new TestBean("x", "x", "x")));
Ausführungsergebnis
key:B value:Butaman Anman Chukaman Beschreibung:Enthält Schweinefleisch
collect Es scheint verwendet zu werden, wenn Sie es als Sammlung anstelle eines einzelnen Elements wie Optional zurückgeben möchten. Sammlung → Als Stream bearbeiten → Als Sammlung ausgeben Ich denke, ich benutze es ziemlich oft.
Wenn Sie die verschiedenen Schnittstellen, die die Argumente für das Sammeln sind, ernsthaft selbst implementieren möchten, müssen Sie ungefähr 5 abstrakte Methoden schreiben, damit die in der Collectors-Klasse bereitgestellte statische Methode einfach verwendet werden kann.
collect
List<TestBean> newlist = list.stream()
.filter(x -> x.getKey().equals("C"))
.collect(Collectors.toList());
System.out.println(newlist.get(0).toString());
Ausführungsergebnis
key:C value:Chukaman Beschreibung:Es ist ein allgemeiner Begriff für Anmanbutaman usw.
min Wie der Name schon sagt, wird der kleinste als optional zurückgegeben. Das Minimum ist dasselbe wie für das Sortieren, und der Komparator wird implementiert und definiert. Geben Sie in diesem Beispiel das Element mit dem Namen key an.
min
Optional<TestBean> op = list.stream()
.min((x, y) -> x.getKey().compareTo(y.getKey()));
System.out.println(op.orElse(new TestBean("x", "x", "x")).toString());
Ausführungsergebnis
key:A value:Anman Beschreibung:Enthält Anko
max Das Gegenteil von min!
max
Optional<TestBean> op = list.stream()
.max((x, y) -> x.getKey().compareTo(y.getKey()));
System.out.println(op.orElse(new TestBean("x", "x", "x")).toString());
Ausführungsergebnis
key:C value:Chukaman Beschreibung:Es ist ein allgemeiner Begriff für Anmanbutaman usw.
count Wie der Name schon sagt, wird die Anzahl der Stream-Elemente zurückgegeben.
count
System.out.println(list.stream().count());
Ausführungsergebnis
3
anyMatch Während ich lese, gibt es true zurück, wenn eine der Bedingungen in Stream erfüllt ist. In diesem Beispiel suchen wir einen Artikel mit dem Schlüssel "A".
anyMatch
boolean matched = list.stream().anyMatch(x -> x.getKey().equals("A"));
if (matched) {
System.out.println("Da war ein Mann!");
}
Ausführungsergebnis
Da war ein Mann!
allMatch Bis ich dies gelesen habe, wird true zurückgegeben, wenn alle Elemente in Stream die angegebenen Bedingungen erfüllen.
allMatch
boolean matched = list.stream().allMatch(x -> !x.getKey().equals("Z"));
if (matched) {
System.out.println("Nicht jeder ist Z!");
}
Ausführungsergebnis
Nicht jeder ist Z!
noneMatch Gibt true zurück, wenn der Stream nicht vorhanden ist.
noneMatch
boolean noMatched = list.stream().noneMatch(x -> x.getKey().equals("Z"));
if (noMatched) {
System.out.println("Es gab keinen Z-Krieger");
}
Ausführungsergebnis
Es gab keinen Z-Krieger
findFirst Wie der Name schon sagt, wird der erste zurückgegeben!
findFirst
Optional<TestBean> op = list.stream().findFirst();
System.out.println(op.orElse(new TestBean("x", "x", "x")).toString());
Ausführungsergebnis
key:B value:Butaman Beschreibung:Enthält Schweinefleisch
findAny Es geht seinen Namen durch und gibt etwas zurück. Ich spreche über etwas ... Ich weiß nicht wirklich, was zurückkommen wird. Sie können kein Argument angeben. Als ich es mit einem sequentiellen Stream versuchte, wurde das erste Element zurückgegeben, aber es scheint, dass es keine Garantie gibt. (08.12.2018 Ich habe einen Kommentar erhalten und korrigiert)
findAny
Optional<TestBean> op = list.stream().findAny();
System.out.println(op.orElse(new TestBean("x", "x", "x")).toString());
Ausführungsergebnis
key:B value:Butaman Beschreibung:Enthält Schweinefleisch
Ich habe das Bean-Wertelement im Stream mit einer festen Zeichenfolge überschrieben. Sicherlich hat sich die Quelle (Liste) nicht geändert.
python
System.out.println("【Vor】 ändern");
for (TestBean bean : list) {
System.out.println(bean);
}
list.stream().map(x -> {
x.setValue("Ich habe es geändert!");
return x;
});
System.out.println("[Nach der veränderung]");
for (TestBean bean : list) {
System.out.println(bean);
}
Ausführungsergebnis
【Vor】 ändern
key:B value:Butaman Beschreibung:Enthält Schweinefleisch
key:A value:Anman Beschreibung:Enthält Anko
key:C value:Chukaman Beschreibung:Es ist ein allgemeiner Begriff für Anmanbutaman usw.
[Nach der veränderung]
key:B value:Butaman Beschreibung:Enthält Schweinefleisch
key:A value:Anman Beschreibung:Enthält Anko
key:C value:Chukaman Beschreibung:Es ist ein allgemeiner Begriff für Anmanbutaman usw.
Erstellen Sie eine Liste von 150 Millionen Speichern Sie darin Zufallszahlen von 0 bis 99 Erstellen Sie eine weitere Liste, indem Sie nur die Elemente extrahieren, in denen 99 gespeichert ist Ich habe einen verschwenderischen Prozess gemacht und ihn gemessen.
Infolgedessen gibt es keinen großen Unterschied zwischen Liste und Stream. paralellStream war offensichtlich schnell.
python
final int loopsize = 150000000;
final int randomrange = 100;
final int findnum = 99;
// create many data
System.out.println("Während der Testdatengenerierung...");
List<Integer> list = IntStream.range(0, loopsize)
.mapToObj(x -> new Random().nextInt(randomrange))
.collect(Collectors.toList());
// byList
LocalDateTime starttime = start("--- byList ---");
List<Integer> newlist = new ArrayList<>();
for (Integer i : list) {
if (i.intValue() == findnum) {
newlist.add(i);
}
}
end(starttime, findnum, newlist);
// byStream
starttime = start("--- byStream ---");
List<Integer> streamlist = list.stream()
.filter(x -> x.intValue() == findnum).collect(Collectors.toList());
end(starttime, findnum, streamlist);
// byParalellStream
starttime = start("--- byParalellStream ---");
List<Integer> paralellStreamlist = list.parallelStream()
.filter(x -> x.intValue() == findnum).collect(Collectors.toList());
end(starttime, findnum, paralellStreamlist);
}
private static LocalDateTime start(String msg) {
System.out.println("");
System.out.println(msg);
LocalDateTime ldt = LocalDateTime.now();
System.out.println("start: " + ldt);
return ldt;
}
private static void end(LocalDateTime starttime, int findnum,
List<Integer> newlist) {
LocalDateTime elapsed = LocalDateTime.now();
System.out.println("end : " + elapsed);
elapsed = elapsed.minusHours(starttime.getHour());
elapsed = elapsed.minusMinutes(starttime.getMinute());
elapsed = elapsed.minusSeconds(starttime.getSecond());
elapsed = elapsed.minusNanos(starttime.getNano());
System.out
.println("elapsed: " + elapsed.format(DateTimeFormatter.ISO_TIME));
System.out.println(findnum + "Ist" + newlist.size() + "Es gab einen!");
}
Ausführungsergebnis
Während der Testdatengenerierung...
--- byList ---
start: 2018-12-08T15:35:51.584
end : 2018-12-08T15:35:52.039
elapsed: 00:00:00.455
Es waren 1500072 99!
--- byStream ---
start: 2018-12-08T15:35:52.052
end : 2018-12-08T15:35:52.450
elapsed: 00:00:00.398
Es waren 1500072 99!
--- byParalellStream ---
start: 2018-12-08T15:35:52.450
end : 2018-12-08T15:35:52.672
elapsed: 00:00:00.222
Es waren 1500072 99!
Mit parallelStream war dies sicherlich nicht garantiert. In Sequential Stream wurde in der Reihenfolge der Originalquelle (Liste) darauf zugegriffen.
python
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
System.out.println("--- byList ---");
for (int i : list) {
System.out.println(i);
}
System.out.println("--- byStream ---");
list.stream().forEach(i -> System.out.println(i));
System.out.println("--- byParallelStream ---");
list.parallelStream().forEach(i -> System.out.println(i));
System.out
.println("findany by stream:" + list.stream().findAny().orElse(null));
System.out.println("findany by parallelStream:"
+ list.parallelStream().findAny().orElse(null));
Ausführungsergebnis
--- byList ---
1
2
3
4
5
6
7
8
9
10
--- byStream ---
1
2
3
4
5
6
7
8
9
10
--- byParallelStream ---
7
9
6
3
5
2
10
1
4
8
findany by stream:1
findany by parallelStream:7
Es wird eine funktionale Schnittstelle (Verhalten) als Argument anstelle von Daten übergeben. Dies nennt man funktionale Programmierung. Ich konnte es nicht einfach schreiben, weil ich es nur prozedural geschrieben habe.
Ich vergesse es bald und kann es nicht auf einmal schreiben. Anstatt einen Lambda-Ausdruck zu verwenden, habe ich eine anonyme Klasse mit der neuen Schnittstelle () {...} erstellt, eine abstrakte Methode implementiert und durch einen Lambda-Ausdruck ersetzt .. Ich schäme mich zu sagen ... Nun, Sie werden sich bald daran gewöhnen.
Vielen Dank an alle Autoren!
Grundlagen der Stream-API https://qiita.com/Takmiy/items/f1d44dfde0d3a906d321
Übersicht über Java 8-Funktion, Verbraucher, Lieferant, Prädikat https://qiita.com/subaru44k/items/c55d9b9fc419f0d09c64
Was ist funktionale Programmierung und was ist Lambda? https://qiita.com/lrf141/items/98ffbeaee42d30cca4dc
Unterschied zwischen Stream Map und FlatMap https://qiita.com/KevinFQ/items/97137efb2159009b60e1
Außerhalb von Qiita. Es beschreibt vom Zweck der Stream-API bis zu den experimentellen Ergebnissen. http://d.hatena.ne.jp/nowokay/20130506
Recommended Posts