Flux de type primitif en Java 8

Flux de type primitif en 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 autres séquences d'éléments -conveniently and more efficiently - 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 etdouble - la bibliothèque standard comprend trois implémentations spécialisées dans les primitives:IntStream,LongStream, et DoubleStream.

Les flux primitifs sont limités principalement en raison 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 quemin,max,sum etaverage:

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éé nosIntStream en utilisantjava.util.Arrays.stream(int[]), puis nous avons utilisé la méthodemin() pour obtenir l'entier le plus bas en tant quejava.util.OptionalInt et enfin appelégetAsInt() pour obtenir leint) s valeur.

Une autre façon de créer unIntStream consiste à utiliserIntStream.of(int…). La méthodemax() 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éthodesum() et nous n'avons pas besoin d'utilisergetAsInt() car elle renvoie déjà le résultat sous forme de valeurint:

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

Nous invoquons la méthodeaverage() pour obtenir la moyenne des valeurs entières et comme nous pouvons le voir, nous devrions utilisergetAsDouble() car elle renvoie une valeur de typedouble.

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

4. Gamme

Nous pouvons également créer unIntStream 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èresrange() etrangeClosed().

La différence est que la fin derange() est exclusive alors qu'elle est incluse dansrangeClosed().

Les méthodes de plage ne sont disponibles que pourIntStream etLongStream.

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 bien pour les utiliser comme remplacement de boucle for-each, c'est que nous pouvons également tirer parti 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 les 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éthodeboxed():

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éthodesmapToXxx etflatMapToXxx 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 échantillons de code peuvent être trouvésover on GitHub.