J'ai parcouru plusieurs questions précédentes telles que Conservation de l'ordre de rencontre dans le flux java, cette réponse de Brian Goetz, ainsi que le javadoc pour Stream.reduce () et le package java.util.stream javadoc, et pourtant je n'arrive toujours pas à comprendre ce qui suit:

Prenez ce morceau de code:

  public static void main(String... args) {
    final String[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
    System.out.println("Alphabet: ".concat(Arrays.toString(alphabet)));
    System.out.println(new HashSet<>(Arrays.asList(alphabet))
          .parallelStream()
          .unordered()
          .peek(System.out::println)
          .reduce("", (a,b) -> a + b, (a,b) -> a + b));
  }

Pourquoi la réduction préserve-t-elle toujours * l'ordre de rencontre?

  • Jusqu'à présent, après plusieurs dizaines d'exécutions, la sortie est la même
7
George Aristy 5 août 2017 à 00:20

2 réponses

Meilleure réponse

Tout d'abord unordered n'implique pas un réel brassage; tout ce qu'il fait, il définit un indicateur pour le pipeline Stream - qui pourrait plus tard être exploité.

Un mélange des éléments sources pourrait potentiellement être beaucoup plus coûteux que les opérations sur le pipeline de flux elles-mêmes, de sorte que l'implémentation pourrait choisir de ne pas le faire (comme dans ce cas).

Pour le moment (testé et examiné les sources) de jdk-8 et jdk-9 - reduce n'en tient pas compte. Notez que cela pourrait très bien changer dans une future build ou version.

De même, lorsque vous dites unordered - vous voulez dire en fait que vous ne vous souciez pas de cet ordre et que le flux renvoyant le même résultat ne constitue pas une violation de cette règle.

Par exemple, notez cette question / réponse qui explique que findFirst par exemple (juste une autre opération de terminal) a changé pour prendre unordered en considération dans java-9 par opposition à java-8.

4
Eugene 4 août 2017 à 22:37

Pour aider à expliquer cela, je vais réduire la portée de cette chaîne à ABCD.

Le flux parallèle divisera la chaîne en deux parties: AB et CD. Lorsque nous allons les combiner plus tard, le résultat du côté AB sera le premier argument passé dans la fonction, tandis que le résultat du côté CD sera le deuxième argument passé dans la fonction. Ceci indépendamment de celui des deux qui termine réellement en premier.

L'opérateur unordered affectera certaines opérations sur un flux, comme une opération limit, il n'affectera pas un simple reduce.

3
Joe C 4 août 2017 à 21:34