[Ein Muss für einen Java-Ingenieurlehrling] Verwendung der Stream-API

Artikelübersicht


Dieser Artikel befasst sich mit der Verwendung der Stream-API. Viele Beispiele und Erklärungen zum Quellcode werden bereitgestellt, damit auch diejenigen, die mit der Stream-API noch nicht vertraut sind, sie verstehen können. Außerdem wird die angewandte Verwendung wie das Strategiemuster mithilfe der Stream-API eingeführt.

Vorteile des Lernens der Stream-API


――Da die Verarbeitung wie Wörter erfolgt, wird die Lesbarkeit verbessert.

Wann kann ich die Stream-API verwenden?


Es kann an Orten verwendet werden, an denen die Schleifenverarbeitung am häufigsten ausgeführt wird, z. B. für Anweisungen.

Verwendung der Stream-API


Der grundlegende Ablauf besteht darin, eine Stream-Instanz zu erstellen, so viele Prozesse auszuführen, wie Sie möchten (Zwischenoperation) und sie schließlich in den gewünschten Zustand zu bringen (Endpunktoperation).

Vergleichen wir **, wenn Sie die Stream-API nicht verwendet haben ** und **, wenn Sie ** verwendet haben, um sich diesen Prozess vorzustellen.

Der unten geschriebene Code zeigt den Quellcode, der die in der Liste gespeicherte Zeichenfolge in Großbuchstaben konvertiert und nur die 4-stellige Zeichenfolge extrahiert und anzeigt.

//Code, der ohne Verwendung der Stream-API geschrieben wurde
List<String> list2 = Arrays.asList("hoge", "foo", "bar","hoga");
		List<String> stream2 = new ArrayList<String>();
		for(String s :list2){
			String sUpperCase = s.toUpperCase();
			if(sUpperCase.length() == 4){
				stream2.add(sUpperCase);
			}
		}
		for(int i = 0; i < stream2.size(); i++){
			System.out.println(stream2.get(i));
		}

/*
Das Ergebnis ist wie folgt
HOGE
HOGA
*/
//Bei Verwendung der Stream-API
		List<String> list1 = Arrays.asList("hoge", "foo", "bar","hoga");
		List<String> stream1 = list1.stream()
								.map(String::toUpperCase)
								.filter(s -> s.length() == 4)
								.collect(Collectors.toList());
		stream1.forEach(System.out::println);

/*
Das Ergebnis ist wie folgt
HOGE
HOGA
*/

Die Verwendung der Stream-API wie diese ist einfacher zu lesen, da Sie nur schreiben müssen, was Sie deklarativ tun möchten. (Es gibt einen Vorteil, da es keine andere Statusänderung gibt und unnötige Verarbeitung aufgrund von Verarbeitungsverzögerung nicht ausgeführt wird.)

Nachdem Sie eine Vorstellung von der Verwendung der Stream-API haben, werde ich Ihnen die Verwendung ausführlich erläutern.

Ich werde den Stromfluss separat wie folgt erklären. ** 1. Stream-Instanzerstellung ** ** 2. Zwischenbetrieb ** ** 3. Endpunktbetrieb **

1. Erstellen Sie eine Stream-Instanz


Es gibt viele Möglichkeiten, eine Stream-Instanz zu erstellen, aber hier sind vier, die Sie möglicherweise am häufigsten verwenden.

Klasse / Schnittstelle Methode Überblick
Collection stream() Stream-Instanzgenerierung aus einer Klasse, die die Collection-Schnittstelle erbt
Arrays stream (T[] array) Erstellen Sie eine Stream-Instanz aus einem Array
Stream of(T… values) Erstellen Sie eine Stream-Instanz basierend auf dem direkten Wert
Stream iterate(T seed, UnaryOperator f) Erstellen Sie eine geordnete unendliche Stream-Instanz

Wie schreibe ich Quellcode

// Collection#stream()
List<String> list = Arrays.asList("hoge", "foo", "bar");
Stream<String> stream = list.stream();

// Arrays#stream (T[] array)
String[] array = {"hoge", "foo", "bar"};
Stream<String> stream2 = Arrays.stream(array);

// Stream#of (T[] array)
Stream<String> stream3 = Stream.of("hoge", "foo", "bar");

// Stream#iterate (T seed, UnaryOperator f)
Stream<Integer> stream4 = Stream.iterate(2, x -> x * 2);

2. Zwischenbetrieb


Zwischenoperationen sind grob in drei Verarbeitungsmethoden unterteilt.

** 1. Ich denke, Sie verstehen, wie eine Stream-Instanz erstellt wird **, daher werde ich die Zwischenoperationen für die generierte Stream-Instanz eingrenzen.

Grenzen Sie die Elemente ein

Da es eingegrenzt ist, ändert sich die Anzahl der Ein- und Ausgänge.

Methode Überblick
filter(Predicate<? super T> predicate) In Prädikat definierter Stream mit nur echten ElementenGib es zurück
limit(long maxSize) Gibt einen Elementstrom vom Anfang des Elements an maxSize zurück
skip(long maxSize) Gibt einen Stream zurück, der Elemente vom Anfang des Elements zu maxSize überspringt
distinct() Vergleicht Elemente mit der Methode equals und gibt einen Stream ohne Duplikate zurück

Wie schreibe ich Quellcode

List<String> list = Arrays.asList("hoge", "foo", "bar","hoga","hoga");
//Nur 4-stellige Zeichenfolge mit Filter extrahiert
System.out.println("****↓ filter****");
list.stream()
	.filter(s -> s.length() == 4)
	.forEach(System.out::println);

/*
Ausgabeergebnis
hoge
hoga
hoga
*/

List<String> list = Arrays.asList("hoge", "foo", "bar","hoga","hoga");
//Mit limit bis zu 3 Strings aus dem ersten Zeichen extrahiert
list.stream()
	.limit(3)
	.forEach(System.out::println);

/*
Ausgabeergebnis
hoge
foo
bar
*/
List<String> list = Arrays.asList("hoge", "foo", "bar","hoga","hoga");
//Ich habe überspringen verwendet, um das Element th Zeichenfolge vom ersten Buchstaben zu überspringen
list.stream()
	.skip(1)
	.limit(2)
	.forEach(System.out::println);

/*
Ausgabeergebnis
foo
bar
*/

List<String> list = Arrays.asList("hoge", "foo", "bar","hoga","hoga");
//Doppelte Zeichenfolgen wurden mit different entfernt
list.stream()
	.distinct()
	.forEach(System.out::println);

/*
Ausgabeergebnis
hoge
foo
bar
hoga
*/
Verarbeitung von Elementen

Die Anzahl der Ein- und Ausgänge ändert sich nicht, da sie nur verarbeitet werden. Sie können beispielsweise von unten nach oben oder von Zeichenfolge zu Anzahl der Zeichen in der Zeichenfolge wechseln.

Methode Überblick
map(Function<? super T, ? extends R> function) Gibt R von T zurück, das von der Funktion als Argument empfangen wurde, und Stream, der mit diesem R als Element generiert wurdeGib es zurück

Wie schreibe ich Quellcode

List<String> list = Arrays.asList("hoge", "foo", "bar","hoga");
list.stream()
	.map(String::length)
	.forEach(System.out::println);

/*
Ausgabeergebnis
4
3
3
4
*/


Elemente sortieren
Methode Überblick
sorted(Comparator<? super T> comparator) Stream verglichen und sortiert nach KomparatorGib es zurück

Wie schreibe ich Quellcode

List<Person> people = Arrays.asList(
		new Person("Suzuki",24),
		new Person("Yamada",53),
		new Person("Jean Baljan",9),
		new Person("Yokouchi",39));

//Nach Alter sortiert
people.stream()
		.sorted(comparing(Person::getAge))
		.forEach(s -> System.out.println(s.toString()));
/*
Ausgabeergebnis
Jean Baljan:9
Suzuki:24
Yokouchi:39
Yamada:53
*/


//Nach Name sortieren.reversed()Bei Verwendung in absteigender Reihenfolge
people.stream()
		.sorted(comparing(Person::getName).reversed())
		.forEach(s -> System.out.println(s.toString()));
}

/*
Ausgabeergebnis
Suzuki:24
Yokouchi:39
Yamada:53
Jean Baljan:9
*/
//Personenklasse oben verwendet
public class Person {
	private String name;
	private int age;
	public Person(String name, int age){
		this.name = name;
		this.age = age;
	}
	public String getName(){
		return name;
	}
	public int getAge(){
		return age;
	}
	public String toString(){
		return name + ":" + age;
	}
}

3. Endpunktbetrieb


Die Endpunktoperation ist die letzte Operation, die eine Stream-Instanz erstellt und Zwischenoperationen abschließt.

Methode Rückgabetyp Inhalt
forEach(Consumer<? super T> consumer) void Der Verbraucher empfängt jedes Element von Stream als Argument und verarbeitet es. Bei paralleler Verarbeitung kann die Reihenfolge nicht garantiert werden, selbst wenn die Originaldaten ein Aggregat wie List sind.
forEachOrdered(Consumer<? super T> consumer) void Wenn jedes Element von Stream die Bestellung garantiert, erhält der Verbraucher jedes Element als Argument in der Reihenfolge und verarbeitet es.
toArray() Object[] Gibt die Elemente von Stream als Array von Objekten zurück
reduce(T unit, BinaryOperator acc) T die Ermäßigung(Falten).. Gibt das Ergebnis der Kombination von Elementen mit der kumulativen Funktion acc für die Einheit Elementeinheit zurück.
collect(Supplier factory, BiConsumer acc, BiConsumer combiner) Ergebnisbehälter Variable Reduzierung. Ab Werk erzeugter variabler Container(Zum Beispiel ArrayList)Fügen Sie andererseits ein Element mit acc hinzu und kombinieren Sie jeden Behälter mit einem Kombinierer.
min(Comparator<? super T> comparator) Optional Gibt das kleinste der Elemente zurück. Verwenden Sie den Argumentvergleicher, um die Größe zu vergleichen. Gibt ein leeres Optional zurück, wenn kein Element vorhanden ist
max(Comparator<? super T> comparator) Optional Gibt das größte der Elemente zurück. Verwenden Sie den Argumentvergleicher, um die Größe zu vergleichen. Gibt ein leeres Optional zurück, wenn kein Element vorhanden ist
count() long Gibt die Anzahl der Elemente zurück, über die Stream verfügt
anyMatch(Predicate<? super T> predicate) boolean Wenn alle Elemente von Stream im Prädikat-Urteil True zurückgeben, wird True als Rückgabewert zurückgegeben.
allMatch(Predicate<? super T> predicate) boolean Wenn alle Elemente von Stream im Prädikat-Urteil True zurückgeben, wird True als Rückgabewert zurückgegeben.
noneMatch(Predicate<? super T> predicate) boolean Wenn keines der Stream-Elemente bei der Prädikatentscheidung True zurückgibt, wird True als Rückgabewert zurückgegeben.
findFirst() Optional Gibt das erste Element der Elemente zurück. Gibt ein leeres Optional zurück, wenn kein Element vorhanden ist
findAny() Optional Gibt ein Element der Elemente zurück. Gibt ein leeres Optional zurück, wenn kein Element vorhanden ist
sum() int / long /double Gibt die Summe der Elemente zurück, über die Stream verfügt. Der Rückgabewert entspricht dem, was der Stream darstellt. Gibt 0 zurück, wenn keine Elemente vorhanden sind
average() OptionalDouble Gibt den Durchschnittswert zurück. Wenn kein Element vorhanden ist, wird Empty OptionalDouble zurückgegeben. Wenn es nicht teilbar ist, wird es auf einen Wert gerundet, der durch einen doppelten Wert dargestellt werden kann.

Wie schreibe ich Quellcode Da die Menge diesmal groß ist, habe ich ein Beispiel geschrieben, indem ich ungefähr 3 entsprechend extrahiert habe. Es gibt einen optionalen Rückgabewert, der später erläutert wird.


List<Person> people = Arrays.asList(
		new Person("Suzuki",24),
		new Person("Yamada",53),
		new Person("Jean Baljan",9),
		new Person("Yokouchi",39));

//Nach Alter sortieren und in Liste speichern
List<Person> sortedPeople = people.stream()
								.sorted(comparing(Person::getAge))
								.collect(Collectors.toList());
System.out.println(sortedPeople);
/*
Ausgabeergebnis
[Jean Baljan:9,Suzuki:24,Yokouchi:39,Yamada:53]
 */
//Sortieren Sie nach Alter in absteigender Reihenfolge und erhalten Sie die erste Person
Optional<Person> firstPerson = people.stream()
								.sorted(comparing(Person::getAge).reversed())
								.findFirst();
System.out.println(firstPerson);
/*
Ausgabeergebnis
Optional[Yamada:53]
*/
//Richtig, wenn alle Personen 10 Jahre oder älter sind, andernfalls falsch
boolean ss = people.stream()
					.allMatch(p -> p.getAge() > 10);
System.out.println(ss);
/*
Ausgabeergebnis
false
*/

Über Optional


Was ist optional?

Ein Containerobjekt, das mit oder ohne Nicht-Null-Werten gespeichert werden kann. Es ist nicht erforderlich, eine Null-Po-Verarbeitung wie if (xxx == null) durchzuführen. Bitte lesen Sie es, da es in einem leicht verständlichen Dokument organisiert ist. https://docs.oracle.com/javase/jp/8/docs/api/java/util/Optional.html

Verwendung Optional

Dies ist ein Beispiel für die Methode ifPresent (Consumer <? Super T> consumer). Dieses Programm gibt den ersten Wert aus, der gefunden wird, wenn die Anzahl der Zeichen im Nachnamen 3 oder mehr beträgt.

//Wenn Optional nicht verwendet wird
List<String> people = Arrays.asList("Yamada","Tanaka","Suzuki");
String firsPerson = null;
for(String s : people){
	if(s.length() == 3){
		firsPerson = s;
		break;
	}
}
//Nullprüfung
if(firsPerson != null){
	System.out.println(firsPerson);
}
//Verwenden Sie Optional und führen Sie es nur aus, wenn der Wert vorhanden ist
Optional<String> firstPerson = Stream.of("Yamada","Tanaka","Suzuki")
									.filter(s -> s.length() == 3)
									.findFirst();
firstPerson.ifPresent(System.out::println);

Ruft den angegebenen Verbraucher mit diesem Wert auf, falls vorhanden, andernfalls wird nichts unternommen.

Predicate


Was ist Prädikat?

Gibt den Booleschen Wert des Verarbeitungsergebnisses zurück. Sie können auch Prozesse verbinden, wenn es also einen Prozess gibt, der eine große Anzahl von if-Anweisungen verbindet Es kann effektiv eingesetzt werden.

Verwendung von Predicate

Implementieren Sie einen Prozess, der einen Wert vom Typ T als Argument verwendet und einen booleschen Wert zurückgibt. Der Wert von boolean wird zurückgegeben, indem der Testmethode das Argument T gegeben wird.

Predicate<String> predicate = s -> s.length() == 5;
System.out.println(predicate.test("tarou"));

Function


Was ist Funktion?

Stellt eine Funktion dar, die ein Argument akzeptiert und ein Ergebnis erzeugt.

So verwenden Sie die Funktion

Implementieren Sie den Prozess des Empfangens eines T-Typ-Arguments und des Zurückgebens eines R-Typ-Werts. Sie kann ausgeführt werden, indem Sie der Methode apply das Argument T geben.

Function<String,String> toUpper = s -> s.toUpperCase();
System.out.println(toUpper.apply("tarou"));

Consumer


Was ist optional?

Verwendung Optional

Empfängt einen T-Typ-Wert als Argument und implementiert die Verarbeitung ohne Rückgabewert. Sie kann ausgeführt werden, indem Sie der Methode accept das Argument T geben.

Consumer<String> consumer = string -> System.out.println("Cunsumer : " + string);
consumer.accept("tarou");

Parallelverarbeitung


comming soon

Rekursive Verarbeitung durch verzögerte Auswertung


comming soon

Recommended Posts

[Ein Muss für einen Java-Ingenieurlehrling] Verwendung der Stream-API
[Für Anfänger] So bedienen Sie die Stream-API nach Java 8
Verwendung der Java-API mit Lambda-Ausdrücken
[Java] Verwendung von Map
Verwendung von Java Optional
Verwendung der Java-Klasse
[Java] Verwendung von removeAll ()
Verwendung von Java Map
Verwendung von Java-Variablen
[Java] Einführung in die Stream-API
Verwendung von Truth (Assertion Library für Java / Android)
Zusammenfassung der Java-Kommunikations-API (1) Verwendung von Socket
Zusammenfassung der Java-Kommunikations-API (3) Verwendung von SocketChannel
Zusammenfassung der Java-Kommunikations-API (2) Verwendung von HttpUrlConnection
Verwendung von HttpClient (Get) von Java
Verwendung von SAS-Token für Azure Event Hubs (Java)
[java8] Um die Stream-API zu verstehen
[Einführung in Java] Informationen zur Stream-API
Verwendung von HttpClient (Post) von Java
[Java] Verwendung der Join-Methode
[Verarbeitung × Java] Verwendung von Variablen
Aufrufen und Verwenden der API in Java (Spring Boot)
[JavaFX] [Java8] Verwendung von GridPane
Verwendung von Klassenmethoden [Java]
[Java] Verwendung von List [ArrayList]
Wie verwende ich Klassen in Java?
Java 8 ~ Stream API ~ startet jetzt
[Verarbeitung × Java] Verwendung von Arrays
Verwendung von Java-Lambda-Ausdrücken
[Java] Verwendung der Math-Klasse
Verwendung des Java-Aufzählungstyps
Mehrsprachige Unterstützung für Java Verwendung des Gebietsschemas
Verwendung von binding.pry für die Ansichtsdatei
[Java] Verwendung der File-Klasse
Verwendung der Submit-Methode (Java Silver)
[Leicht verständliche Erklärung! ] Verwendung der Java-Instanz
[Java] Verwendung der toString () -Methode
Studieren der Verwendung des Konstruktors (Java)
[Verarbeitung × Java] Verwendung der Schleife
Verwendung und Definition von Java-Klassen, Importieren
[Ruby] Wie man Slice für Anfänger benutzt
[Leicht verständliche Erklärung! ] Verwendung des Java-Polymorphismus
[Java] [Maven3] Zusammenfassung der Verwendung von Maven3
[Verarbeitung × Java] Verwendung der Klasse
Verwendung der Java Scanner-Klasse (Hinweis)
[Verarbeitung × Java] Verwendung der Funktion
[Leicht verständliche Erklärung! ] Verwendung von ArrayList [Java]
[Java] Verwendung der Calendar-Klasse
[Java] Erfahren Sie, wie Sie Optional richtig verwenden
[Leicht verständliche Erklärung! ] Verwendung von Java-Überladung
try-catch-finally Ausnahmebehandlung Verwendung von Java
[Leicht verständliche Erklärung! ] Verwendung der Java-Kapselung
Java Stream API