Inspiriert von dieser Frage begann ich um mit geordneten vs ungeordneten Streams zu spielen, parallele vs sequentielle Streams und terminale Operationen, die die Reihenfolge der Begegnung gegen terminale Operationen respektieren, die sie nicht respektieren.
In einer Antwort auf die verknüpfte Frage wird ein Code ähnlich dem folgenden angezeigt:
%Vor% Und die Listen sind in der Tat unterschiedlich. Die unordered
-Liste ändert sich sogar von einem Lauf zum nächsten und zeigt, dass das Ergebnis tatsächlich nicht deterministisch ist.
Also habe ich dieses andere Beispiel erstellt:
%Vor% Und ich habe erwartet, ähnliche Ergebnisse zu sehen, da der Stream sowohl parallel als auch ungeordnet ist (vielleicht ist unordered()
redundant, da es bereits parallel ist). Die resultierende Liste ist jedoch geordnet, d. H. Sie ist gleich der Quellenliste.
Also meine Frage ist, warum die gesammelten Liste bestellt ist? Beherzt collect
die Begegnungs- Reihenfolge auch für parallele, ungeordnete Streams? Ist es der spezifische Collectors.toCollection(...)
-Kollektor, der die Begegnung-Reihenfolge erzwingt?
Collectors.toCollection
gibt eine Collector
zurück, der die Eigenschaft Collector.Characteristics.UNORDERED
fehlt. Ein anderer Kollektor, der Collector.Characteristics.UNORDERED
angegeben hat, verhält sich möglicherweise anders.
Das heißt: "ungeordnet" bedeutet keine Garantien , nicht garantiert zu variieren. Wenn die Bibliothek es am einfachsten findet, eine ungeordnete Sammlung wie bestellt zu behandeln, ist es erlaubt tun Sie es, und dieses Verhalten darf die Veröffentlichung freilassen, dienstags oder wenn Vollmond ist.
(Beachten Sie auch, dass Collectors.toCollection
nicht die Verwendung einer parallelen Auflistungsimplementierung erfordert, wenn Sie parallele Datenströme verwenden; toCollection(ArrayList::new)
würde funktionieren. Das liegt daran, dass der Kollektor nicht das Merkmal Collector.Characteristics.CONCURRENT
hat Daher wird eine Sammlungsstrategie verwendet, die auch bei parallelen Streams für nicht gleichzeitige Sammlungen verwendet wird.)
Wenn Sie einen ungeordneten Stream verwenden, aber einen Collector, der nicht UNORDERED
ist, oder umgekehrt, bezweifle ich, dass Sie vom Framework irgendwelche Garantien erhalten. Wenn es einen Tisch gäbe, würde es heißen: "Here findFirst
variiert hier, obwohl findFirst
inhärent eine geordnete Operation ist - unordered().findFirst()
wird äquivalent zu findAny()
.
Für Stream.collect
glaube ich, dass die aktuelle Implementierung drei Strategien hat, zwischen denen sie wählt:
Unter der aktuellen Implementierung habe ich java-8 und java-9 überprüft, dass das ungeordnete Flag für die collect
-Phase für nicht-gleichzeitige Kollektoren ignoriert wird ( Collector.Characteristics.UNORDERED
ist nicht gesetzt). Die Implementierungen dürfen das tun, irgendwie ähnlich Frage .
In derselben Frage, die Sie verlinkt haben, habe ich ein Beispiel dafür gegeben, wie findFirst
tatsächlich von jdk-8 in jdk-9 geändert wurde.
Stream#collect
gibt eine split
zurück, der die Eigenschaft merge
fehlt. Ein anderer Kollektor, der Collectors#toList
angegeben hat, verhält sich möglicherweise anders.
Das heißt: "ungeordnet" bedeutet keine Garantien , nicht garantiert zu variieren. Wenn die Bibliothek es am einfachsten findet, eine ungeordnete Sammlung wie bestellt zu behandeln, ist es erlaubt tun Sie es, und dieses Verhalten darf die Veröffentlichung freilassen, dienstags oder wenn Vollmond ist.
(Beachten Sie auch, dass %code% nicht die Verwendung einer parallelen Auflistungsimplementierung erfordert, wenn Sie parallele Datenströme verwenden; %code% würde funktionieren. Das liegt daran, dass der Kollektor nicht das Merkmal %code% hat Daher wird eine Sammlungsstrategie verwendet, die auch bei parallelen Streams für nicht gleichzeitige Sammlungen verwendet wird.)
Wenn Sie einen ungeordneten Stream verwenden, aber einen Collector, der nicht %code% ist, oder umgekehrt, bezweifle ich, dass Sie vom Framework irgendwelche Garantien erhalten. Wenn es einen Tisch gäbe, würde es heißen: "Here
Für %code% glaube ich, dass die aktuelle Implementierung drei Strategien hat, zwischen denen sie wählt:
Unter der aktuellen Implementierung habe ich java-8 und java-9 überprüft, dass das ungeordnete Flag für die %code% -Phase für nicht-gleichzeitige Kollektoren ignoriert wird ( %code% ist nicht gesetzt). Die Implementierungen dürfen das tun, irgendwie ähnlich Frage .
In derselben Frage, die Sie verlinkt haben, habe ich ein Beispiel dafür gegeben, wie %code% tatsächlich von jdk-8 in jdk-9 geändert wurde.
Inspiriert von dieser Frage begann ich um mit geordneten vs ungeordneten Streams zu spielen, parallele vs sequentielle Streams und terminale Operationen, die die Reihenfolge der Begegnung gegen terminale Operationen respektieren, die sie nicht respektieren.
In einer Antwort auf die verknüpfte Frage wird ein Code ähnlich dem folgenden angezeigt:
%Vor%Und die Listen sind in der Tat unterschiedlich. Die %code% -Liste ändert sich sogar von einem Lauf zum nächsten und zeigt, dass das Ergebnis tatsächlich nicht deterministisch ist.
Also habe ich dieses andere Beispiel erstellt:
%Vor%Und ich habe erwartet, ähnliche Ergebnisse zu sehen, da der Stream sowohl parallel als auch ungeordnet ist (vielleicht ist %code% redundant, da es bereits parallel ist). Die resultierende Liste ist jedoch geordnet, d. H. Sie ist gleich der Quellenliste.
Also meine Frage ist, warum die gesammelten Liste bestellt ist? Beherzt %code% die Begegnungs- Reihenfolge auch für parallele, ungeordnete Streams? Ist es der spezifische %code% -Kollektor, der die Begegnung-Reihenfolge erzwingt?
die Dokumentation Stream # collect hat bereits erwähnt:
Bei einer parallelen Ausführung können mehrere Zwischenergebnisse instanziiert , gefüllt und zusammengeführt sein, um die Isolation veränderbarer Datenstrukturen aufrechtzuerhalten. Daher ist keine zusätzliche Synchronisation für eine parallele Reduktion erforderlich, selbst wenn sie parallel mit nicht threadsicheren Datenstrukturen (z. B. ArrayList) ausgeführt wird.
was bedeutet, dass %code% zwei primäre Dinge tut: %code% & amp; %Code%.
aber ich habe ein spezielles Beispiel in jdk-8, dass Sie die verschiedenen Ergebnisse abrufen können, :). wenn ein ungeordneter Stream erstellt wird, Stream # generieren , dann können Sie verschiedene Ergebnisse für %code% abrufen, zum Beispiel:
%Vor% %Vor%Tags und Links java java-8 java-stream