Java 8 Stream skip () vs limit ()

1. Introduction

Dans ce court article, nous parlerons des méthodes skip () et limit () de l'API Java Stream et mettrons en évidence leurs similitudes et leurs différences.

Même si ces deux opérations peuvent sembler assez similaires au début, elles se comportent en fait très différemment et ne sont pas interchangeables. En fait, ils sont complémentaires et peuvent être utiles lorsqu'ils sont utilisés ensemble. Continuez à lire pour en savoir plus sur eux.

2. La méthode skip ()

La méthode skip (n) est une opération intermédiaire qui supprime les n premiers éléments d'un flux . Le paramètre n ne peut pas être négatif, et s'il est supérieur à la taille du flux, skip () renvoie un flux vide.

Voyons un exemple:

Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) .filter(i -> i % 2 == 0) .skip(2) .forEach(i -> System.out.print(i + " "));

Dans ce flux, nous récupérons les nombres pairs du flux, mais nous sautons les deux premiers. Par conséquent, notre résultat est:

6 8 10

Lorsque ce flux est exécuté, forEach commence à demander des éléments. Lorsqu'elle arrive à skip () , cette opération sait que les deux premiers éléments doivent être supprimés, donc elle ne les ajoute pas au flux résultant. Après cela, il crée et renvoie un flux avec les éléments restants.

Pour ce faire, l' opération skip () doit conserver l'état des éléments vus à chaque instant. Pour cette raison, nous disons que skip () est une opération avec état .

3. La méthode limit ()

La méthode limit (n) est une autre opération intermédiaire qui renvoie un flux pas plus long que la taille demandée . Comme précédemment, le paramètre n ne peut pas être négatif.

Utilisons-le dans un exemple:

Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) .filter(i -> i % 2 == 0) .limit(2) .forEach(i -> System.out.print(i + " "));

Dans ce cas, nous ne prenons que deux nombres pairs de notre flux d' int :

2 4

Comme c'est le cas avec l' opération skip () , limit () est également une opération avec état puisqu'elle doit conserver l'état des éléments qui sont en cours de récupération.

Mais contrairement à skip () , qui consomme tout le flux, dès que limit () atteint le nombre maximum d'éléments, il ne consomme plus d'éléments et renvoie simplement le flux résultant. Par conséquent, nous disons que limit () est une opération de court-circuit .

Lorsque vous travaillez avec des flux infinis, limit () peut être très utile pour tronquer un flux en un flux fini:

Stream.iterate(0, i -> i + 1) .filter(i -> i % 2 == 0) .limit(10) .forEach(System.out::println);

Dans cet exemple, nous tronquons un flux infini de nombres en un flux avec seulement dix nombres pairs.

4. Combinaison de skip () et limit ()

Comme nous l'avons mentionné précédemment, les opérations de saut et de limite sont complémentaires, et si nous les combinons, elles peuvent être très utiles dans certains cas.

Imaginons que nous voulions modifier notre exemple précédent pour qu'il obtienne des nombres pairs par lots de dix. Nous pouvons le faire simplement en utilisant à la fois skip () et limit () sur le même flux:

private static List getEvenNumbers(int offset, int limit) { return Stream.iterate(0, i -> i + 1) .filter(i -> i % 2 == 0) .skip(offset) .limit(limit) .collect(Collectors.toList()); }

Comme nous pouvons le voir, nous pouvons paginer à travers le flux assez facilement avec cette méthode. Même s'il s'agit d'une pagination très simpliste, nous pouvons voir à quel point cela peut être puissant lors du découpage d'un flux.

5. Conclusion

Dans ce bref article, nous avons montré les similitudes et les différences des méthodes skip () et limit () de l'API Java Stream. Nous avons également implémenté quelques exemples simples pour montrer comment nous pouvons utiliser ces méthodes.

Comme toujours, le code source complet des exemples est disponible à l'adresse over sur GitHub.