74 votes

Stream.peek() méthode dans Java 8 vs Java 9

Je suis dans le progrès de l'apprentissage par le biais de Java 8 les expressions lambda et voudrais poser une question sur le morceau suivant du code Java relatives à l' peek méthode dans l'interface de la fonction que j'ai rencontré.

Sur l'exécution du programme sur les IDE, il ne donne aucune réponse. Je m'attendais à ce qu'il donnerait 2, 4, 6.

import java.util.Arrays;
import java.util.List;

public class Test_Q3 {

    public Test_Q3() {
    }

    public static void main(String[] args) {
        List<Integer> values = Arrays.asList(1, 2, 3);
        values.stream()
              .map(n -> n * 2)
              .peek(System.out::print)
              .count();
    }
}

66voto

Eugene Points 6271

Je suppose que vous êtes l'exécution de ce sous Java 9? Vous n'êtes pas altérer l' SIZED de la propriété du flux, alors il n'est pas nécessaire pour exécuter map ou peek à tous.

En d'autres mots, tout ce que vous aimez est sur count comme le résultat final, mais en attendant vous ne modifiez pas la taille initiale de l' List de toute manière (via filter , par exemple, ou distinct) Cette optimisation fait dans les cours d'eau.

Btw, même si vous ajoutez un mannequin filtre cela permettra de montrer ce que vous attendez:

values.stream ()
      .map(n -> n*2)
      .peek(System.out::print)
      .filter(x -> true)
      .count();

65voto

Eran Points 35360

Voici quelques citations de la Javadoc de Flux interface:

Un flux de mise en œuvre est permise une marge de manœuvre importante dans l'optimisation du calcul du résultat. Par exemple, un flux de mise en œuvre est libre d'éluder les opérations (ou les étapes) à partir d'un stream -- et donc éluder l'invocation de paramètres comportementaux -- si elle peut prouver qu'elle n'aurait pas d'incidence sur le résultat du calcul. Cela signifie que les effets secondaires des paramètres comportementaux ne peuvent pas toujours être exécuté et ne doit pas être invoqué, à moins d'indication contraire (par exemple par l'exploitation du terminal forEach et forEachOrdered). (Pour un exemple d'une telle optimisation, voir l'API note documentée sur l'opération count (). Pour plus de détails, voir la section effets de la flux de la documentation du paquet.)

Et plus particulièrement de la Javadoc de count() méthode:

API Note:

Une mise en œuvre peut choisir de ne pas exécuter le flux du pipeline (de façon séquentielle ou en parallèle), si elle est capable de calcul du comte directement à partir du flux de la source. Dans ce cas, aucune source d'éléments seront traversés et pas les opérations intermédiaires seront évaluées. Paramètres comportementaux avec les effets secondaires, qui sont fortement déconseillés sauf inoffensif des cas tels que le débogage, peuvent être affectés. Par exemple, considérez les points suivants stream:

List<String> l = Arrays.asList("A", "B", "C", "D");
long count = l.stream().peek(System.out::println).count();

Le nombre d'éléments couverts par le flux de la source, une Liste, est connu et l'exploitation intermédiaire, coup d'oeil, ne pas injecter dans ou supprimer des éléments dans le flux (comme cela peut être le cas pour flatMap ou filtre opérations). Ainsi, le nombre est la taille de la Liste et il n'est pas nécessaire d'exécuter le pipeline et, comme effet secondaire, d'imprimer la liste des éléments.

Ces citations apparaissent uniquement sur la Javadoc de Java 9, donc ça doit être une nouvelle optimisation.

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