3 votes

pourquoi la fonction combiner n'est pas exécutée dans l'opération de réduction de flux java-8 ?

J'essaie de comprendre comment fonctionne la méthode de réduction dans les flux.

Stream.of(1,2,3,4,5,6,7).reduce(new ArrayList<>(),
(List<Integer> l, Integer a) -> {l.add(a);return l;},
(List<Integer> l1, List<Integer> l2) -> {
System.out.println("l1 is" + l1 + "l2 is " + l2);
l1.addAll(l2);
return l1;
}).forEach(System.out::println);

La ligne System.out.println("l1 is" + l1 + "l2 is " + l2) ne sera jamais imprimé. Je peux comprendre ce qui se passe dans (List<Integer> l, Integer a) -> {l.add(a);return l;}
Quelqu'un peut-il expliquer pourquoi il n'est pas imprimé ? La documentation java dit function for combining two values, which must be compatible with the accumulator function

Merci, Amar

4voto

JB Nizet Points 250258

Elle n'est appelée que lorsque le flux est parallèle. Dans ce cas, les valeurs du flux sont divisées en deux (de manière récursive), chaque moitié est réduite à une liste, puis les deux listes doivent être combinées ensemble.

Notez que la réduction n'est pas censée modifier les valeurs (les listes, dans ce cas) reçues en argument. Elle est censée retourner une nouvelle valeur. C'est ce que fait une réduction mutable (i.e. collect() ) est un bien meilleur choix dans ce cas.

3voto

holi-java Points 15887

Il a décrit dans java.util.stream résumé du paquet comme ci-dessous :

<U> U reduce(U identity,
          BiFunction<U, ? super T, U> accumulator,
          BinaryOperator<U> combiner);

En combinateur combine deux partiel pour produire une nouvelle partiel résultat. ( Le combineur est nécessaire dans les réductions parallèles où l'entrée est partitionnée, une accumulation partielle est calculée pour chaque partition, puis les résultats partiels sont combinés pour produire un résultat final).

le site "nécessaire" implique que si votre flux est vide ou ne contient que simple élément dans le courant, le combiner ne sera jamais appelé dans un flux parallèle.

Donc si vous voulez voir "l1 is" + l1 + "l2 is " + l2 est imprimé, vous devez l'exécuter dans un flux parallèle, par exemple :

//                       v--- make the stream run in parallel   
Stream.of(1,2,3,4,5,6,7).parallel().reduce(...).forEach(System.out::println);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X