Flux de type primitif dans Java 8

1. Introduction

L'API Stream était l'une des fonctionnalités clés ajoutées à Java 8.

En bref, l'API nous permet de traiter des collections et d'autres séquences d'éléments - de manière pratique et plus efficace - en fournissant une API déclarative.

2. Flux primitifs

Les flux fonctionnent principalement avec des collections d'objets et non avec des types primitifs.

Heureusement, pour fournir un moyen de travailler avec les trois types primitifs les plus utilisés - int, long et double - la bibliothèque standard comprend trois implémentations spécialisées primitives: IntStream , LongStream et DoubleStream .

Les flux primitifs sont limités principalement à cause de la surcharge de boxing et parce que la création de flux spécialisés pour d'autres primitives n'est pas très utile dans de nombreux cas.

3. Opérations arithmétiques

Commençons par quelques méthodes intéressantes pour les opérations arithmétiques très utilisées telles que min , max , sum et average:

int[] integers = new int[] {20, 98, 12, 7, 35}; int min = Arrays.stream(integers) .min() .getAsInt(); // returns 7

Passons maintenant en revue l'extrait de code ci-dessus pour comprendre ce qui se passe.

Nous avons créé notre IntStream en utilisant java.util.Arrays.stream (int []) , puis nous avons utilisé la méthode min () pour obtenir l'entier le plus bas comme java.util.OptionalInt et enfin appelé getAsInt () pour obtenir la valeur int .

Une autre façon de créer un IntStream consiste à utiliser IntStream.of (int…) . La méthode max () retournera le plus grand entier:

int max = IntStream.of(20, 98, 12, 7, 35) .max() .getAsInt(); // returns 98

Ensuite - pour obtenir la somme des entiers, nous appelons simplement la méthode sum () et nous n'avons pas besoin d'utiliser getAsInt () car elle renvoie déjà le résultat sous forme de valeur int :

int sum = IntStream.of(20, 98, 12, 7, 35).sum(); // returns 172

Nous invoquons la méthode average () pour obtenir la moyenne des valeurs entières et comme nous pouvons le voir, nous devrions utiliser getAsDouble () car elle renvoie une valeur de type double .

double avg = IntStream.of(20, 98, 12, 7, 35) .average() .getAsDouble(); // returns 34.4

4. Gamme

Nous pouvons également créer un IntStream basé sur une plage:

int sum = IntStream.range(1, 10) .sum(); // returns 45 int sum = IntStream.rangeClosed(1, 10) .sum(); // returns 55

Comme le montre l'extrait de code ci-dessus, il existe deux façons de créer une plage de valeurs entières range () et rangeClosed () .

La différence est que la fin de range () est exclusive alors qu'elle est inclusive dans rangeClosed () .

Les méthodes de plage ne sont disponibles que pour IntStream et LongStream .

Nous pouvons utiliser range comme une forme sophistiquée d'une boucle for-each:

IntStream.rangeClosed(1, 5) .forEach(System.out::println);

Ce qui est bon pour les utiliser comme remplacement de boucle for-each, c'est que nous pouvons également profiter de l'exécution parallèle:

IntStream.rangeClosed(1, 5) .parallel() .forEach(System.out::println);

Aussi utiles que soient ces boucles sophistiquées, il est toujours préférable d'utiliser les boucles for traditionnelles au lieu de la boucle fonctionnelle pour des itérations simples en raison de la simplicité, de la lisibilité et des performances dans certains cas.

5. Boxe et déballage

Il y a des moments où nous devons convertir des valeurs primitives en leurs équivalents wrapper.

Dans ces cas, nous pouvons utiliser la méthode boxed () :

List evenInts = IntStream.rangeClosed(1, 10) .filter(i -> i % 2 == 0) .boxed() .collect(Collectors.toList());

Nous pouvons également convertir le flux de classe wrapper en flux primitif:

// returns 78 int sum = Arrays.asList(33,45) .stream() .mapToInt(i -> i) .sum();

Nous pouvons toujours utiliser les méthodes mapToXxx et flatMapToXxx pour créer des flux primitifs.

6. Conclusion

Java Streams est un ajout très puissant au langage. Nous avons à peine effleuré la surface des flux primitifs ici, mais comme vous pouvez déjà les utiliser pour être productif.

Et, comme toujours, des exemples de code peuvent être trouvés sur GitHub.