Überraschend tiefe Java-Liste Inversion-Stream-Verarbeitung

Beachten Sie, dass es unerwartet schwierig war, die Liste in Java zu invertieren.

[1, 2, 3].reverse

In Ruby lässt sich das Array leicht invertieren, wie in ↑ gezeigt. Ich dachte, dass Java standardmäßig auch eine Inversion haben würde, wie zum Beispiel die Stream-API.

list.stream().reverse();

Ich konnte das nicht machen. Ich habe nach verschiedenen Stream-bezogenen Elementen gesucht, sie aber nicht gefunden, sodass ich in Schwierigkeiten war.

Vorerst die Torheit, die Liste mit der for-Anweisung von der anderen Seite zu drehen, um eine invertierte Liste zu generieren. .. ..

Also habe ich versucht, ** 3 Möglichkeiten zum Umkehren der Liste ** zusammenzufassen.

1. Verwendung der am häufigsten verwendeten Collections.reverse

Dies ist die Standardmethode, die von der Standardbibliothek bereitgestellt wird.

List<String> list = Arrays.asList("a", "b", "c", "d", "e", "f");
Collections.reverse(list);
// list = [f, e, d, c, b, a]

Beachten Sie, dass dieser Prozess list destruktiv ändert. "Sammlungen" ist übrigens eine Sammlung von Prozessen zum Bearbeiten von Sammlungen wie "Liste" und "Set". Zum Beispiel "mischen" und "sortieren".

2. Verwendung von Deque

Wenn Sie die Struktur häufig nach rechts und links durchlaufen, empfiehlt es sich, sie in eine bidirektionale Liste umzuwandeln.

Deque<String> deque = new LinkedList<>(list);
//bestellen
for(String s: deque) {
	//Verarbeitung von s
}
//Umkehren
Iterator<String> iter = deque.descendingIterator();
while(iter.hasNext()) {
	String s = iter.next();
	//Verarbeitung von s
}

Der Nachteil ist jedoch, dass es sich um ein kleines Legacy-Schreiben handelt. .. ..

3. Verwendung der Collect of Stream-API

Sie können auch die Stream-API verwenden. Die Stream-Verarbeitung selbst ist grundsätzlich unabhängig von der Reihenfolge der Elemente und kann unabhängig für jedes Element verarbeitet werden. Andererseits sind wir nicht gut in der Verarbeitung von Auftragsbeziehungen. Die Reihenfolge kann jedoch garantiert und zum Umkehren verwendet werden.

//Ein bisschen lang. .. .. Wenn der Vorgang zum Abrufen der Liste in umgekehrter Reihenfolge jedoch nicht viele Male angezeigt wird
List<String> reversedList = list.stream().collect(ArrayList::new, (l, e) -> l.add(0, e), (l, subl) -> l.addAll(0, subl));

collect ist eine Methode, die den Aggregationsprozess beschreibt.

  1. ArrayList :: new bestimmt die Klasse für die Aggregation.
  2. "(l, e) -> l.add (0, e)" ist der Hauptteil der Aggregationsverarbeitung. Fügen Sie nun am Anfang der Liste l ein Element hinzu.
  3. (l, subl) -> l.addAll (0, subl) ist ein Zusammenfassungsprozess während der parallelen Ausführung. Fassen Sie im ersten Argument zusammen. (Während der Parallelverarbeitung wird die Liste verarbeitet, indem sie entsprechend aufgeteilt wird, und die aggregierten Ergebnisse werden jeweils ausgegeben. Es ist erforderlich, diese mehreren Ergebnisse zu integrieren.)

Dies ist eine einfache Sache, aber es ist schwierig zu schreiben. ** Ich möchte wirklich wie folgt schreiben. ** ** **

List<String> reversedList = strs.stream().collect(MyCollectors.reverse());

Bereiten Sie in diesem Fall die folgende Collection-Implementierungsklasse vor.

MyCollectors.java


public class MyCollectors {

	public static <T> Collector<T, List<T>, List<T>> reverse() {

		return new Collector<T, List<T>, List<T>>() {
			@Override
			public Supplier<List<T>> supplier() {
				return ArrayList::new;
			}

			@Override
			public BiConsumer<List<T>, T> accumulator() {
				return (l, e) -> l.add(0, e);
			}

			@Override
			public BinaryOperator<List<T>> combiner() {
				return (l, subl) -> {
					l.addAll(0, subl);
					return l;
				};
			}

			@Override
			public Function<List<T>, List<T>> finisher() {
				//Es ist kein endgültiger Aggregationsprozess erforderlich, daher wird die Liste unverändert zurückgegeben
				return l -> l;
			}

			@Override
			public Set<Characteristics> characteristics() {
				//Parallelverarbeitung möglich
				return EnumSet.of(Characteristics.CONCURRENT);
			}
		};
	}
}

Das Schreiben ist mühsam, aber sobald Sie es geschrieben haben, können Sie es problemlos für die Stream-Verarbeitung verwenden.

Bonus) In einigen Fällen ist es nicht erforderlich, eine invertierte Liste zu erstellen

Wenn die invertierte Liste selbst ein Zwischenprodukt ist, muss die Liste nicht invertiert werden. Wenn Sie beispielsweise Zeichenfolgen in umgekehrter Reihenfolge kombinieren möchten, müssen Sie keine invertierte Liste erstellen. Gehen Sie einfach wie folgt vor:

List<String> strs = Arrays.asList("a", "b", "c", "d", "e", "f");
String reverse = strs.stream().reduce((e1, e2) -> e2.concat(e1)).get();
// reverse = "fedcba"

Zusammenfassung

Im Fall von Java kann die Kettenmethode nicht einfach mit nur einem Wort ausgeführt werden, es gibt jedoch drei Hauptmethoden. 0. Verwenden Sie den Java-Standard Collections.reverse

  1. Verwenden Sie Deque
  2. Verwenden Sie die Stream-API Es scheint, dass Sie die Methode verwenden müssen, die zum individuellen Prozess passt.

Recommended Posts

Überraschend tiefe Java-Liste Inversion-Stream-Verarbeitung
Java Memorandum (Liste)
Klonen Sie die Java-Liste.
Java-Thread-Verarbeitung
Java-String-Verarbeitung
[Java] Multithread-Verarbeitung
[Java] Stream-Verarbeitung
Java iterativer Prozess
[Hinweis] Java: Geschwindigkeit der Verarbeitung der Liste nach Zweck
Listenverarbeitung zum Verstehen mit Bildern --java8 stream / javaslang-
JAVA-Konstruktoraufrufverarbeitung
Java zufällig, verschiedene Verarbeitung
[Memo] Java Linked List
Listenverarbeitung zum Verstehen mit Bildern --java8 stream / javaslang --bonus
[Java] Konvertierung von Listentyp / Array-Typ
[Java] Multithread-Verarbeitung - Exklusive Steuerung
[Java] Stream API - Stream-Beendigungsverarbeitung
[Java] Stream API - Stream Zwischenverarbeitung
[Java] Liste der betriebssystemabhängigen Standardbibliotheken
Gemessene Parallelverarbeitung mit Java
Grundlegendes zur Java-Parallelverarbeitung (Einführung)
Listenaggregation in Java (Collectors.groupingBy)
Java-Liste als Gruppe, Sortierung usw.
Deep Copy Collection in Java
Listendatenstruktur [Java / Scala]
Zusammenfassung der Java-Fehlerverarbeitung
[Java] Flache Kopie und tiefe Kopie beim Konvertieren eines Arrays in eine Liste