Maison >Java >javaDidacticiel >Pourquoi `filter()` après `flatMap()` n'est-il pas toujours paresseux dans les flux Java ?

Pourquoi `filter()` après `flatMap()` n'est-il pas toujours paresseux dans les flux Java ?

DDD
DDDoriginal
2024-12-11 19:17:13878parcourir

Why Isn't `filter()` After `flatMap()` Always Lazy in Java Streams?

Pourquoi filter() Après flatMap() n'est pas entièrement paresseux dans les flux Java

Dans les flux Java, filter() est considéré comme un paresseux opération, ce qui signifie qu’elle ne s’exécute pas immédiatement, mais plutôt au point de consommation. Cependant, lorsque filter() suit flatMap(), son comportement s'écarte de la vraie paresse.

Démonstration

Considérez le code suivant :

Stream.of(1, 2, 3)
        .filter(i -> {
            System.out.println(i);
            return true;
        })
        .findFirst()
        .get();

Dans cet exemple, filter() est appliqué à un flux d'entiers. Le résultat montre que la fonction de filtrage n'est invoquée que pour le premier élément, comme prévu dans une évaluation paresseuse.

1
Result: 1

Cependant, dans le code suivant :

Stream.of(1, 2, 3)
        .flatMap(i -> Stream.of(i - 1, i, i + 1))
        .flatMap(i -> Stream.of(i - 1, i, i + 1))
        .filter(i -> {
            System.out.println(i);
            return true;
        })
        .findFirst()
        .get();

Le filtre( ) est appliquée à un flux généré en appliquant deux opérations flatMap(). Malgré le fait que le premier élément du flux aplati satisfait à la condition de filtre, la fonction de filtrage continue d'être invoquée pour les éléments restants.

-1
0
1
0
1
2
1
2
3
Result: -1

Explication

Le la raison de ce comportement est que flatMap() crée un nouveau flux pour chaque élément du flux d'origine. Bien que filter() reste une opération paresseuse, l’opération d’aplatissement ne prend pas en charge la terminaison anticipée. Par conséquent, une fois le processus d'aplatissement commencé, il ne peut pas être interrompu, même si la condition de filtrage est remplie plus tard dans le flux.

Implications

Ce comportement peut conduire à des conséquences, en particulier lorsqu'il s'agit de flux infinis. Par exemple, si le flux d'entrée de l'opération flatMap() est infini, l'opération filter() tentera indéfiniment d'appliquer sa fonction, même s'il est garanti de ne jamais trouver d'élément correspondant.

Correctifs JDK

Le problème décrit ici a été résolu dans Java 10 (et rétroporté vers Java 8). Dans ces versions, flatMap() a été optimisé pour prendre en charge la résiliation anticipée, garantissant que le comportement de filter() et d'autres opérations paresseuses reste cohérent, qu'elles suivent ou non flatMap().

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn