IdentifiantMot de passe
Loading...
Mot de passe oubli� ?Je m'inscris ! (gratuit)
logo

FAQ Langage JavaConsultez toutes les FAQ

Nombre d'auteurs : 42, nombre de questions : 297, derni�re mise � jour : 19 septembre 2017  Ajouter une question

 

Cette FAQ a �t� r�alis�e � partir des questions fr�quemment pos�es sur le forum Java de http://java.developpez.com ainsi que l'exp�rience personnelle des auteurs.

Nous tenons � souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose sont correctes. Les auteurs font leur maximum, mais l'erreur est humaine. Cette FAQ ne pr�tend pas non plus �tre compl�te. Si vous trouvez une erreur, ou que vous souhaitez nous aider en devenant r�dacteur, lisez ceci.

Sur ce, nous vous souhaitons une bonne lecture.

SommaireCollections et StreamsStreams (9)
pr�c�dent sommaire suivant
 

Un stream (data stream ou flux de donn�es ou flot de donn�es) est un concept introduit depuis le JDK�8, et qui repr�sente un ensemble de donn�es. Les flux, en eux-m�mes, ne d�finissent pas une nouvelle mani�re de stocker des donn�es�; ils d�finissent au contraire une nouvelle mani�re d'appliquer des op�rations sur un ensemble de donn�es qui s'apparente, par exemple, � ce qui peut �tre fait en SQL. Ainsi, il est possible de traiter un ensemble de mani�re s�quentielle ou parall�le, ou m�me de le diviser en sous-flux. On peut lui appliquer des filtres, des conversions, des r�ductions, des tris, des traitements ou des op�rations arithm�tiques ou statistiques. De plus, il est possible de convertir un flux en collection ou tableau. La source m�me du flux peut �tre une collection, un tableau ou encore une source de donn�es dynamiques.

Attention�: il ne faut pas confondre les flux sur les donn�es (streams ou data streams) et les flux d�entr�e sortie (I/O streams) qui sont bien plus anciens dans la JVM.

Un stream permet donc de manipuler simplement un flux de donn�es quelconque. L'utilisation d'un flux se compose de trois �tapes�:

  1. La cr�ation du stream � partir d'une source de donn�es (tableau, Collection, fonction de g�n�ration, etc.)�;
  2. Z�ro, une ou plusieurs d�clarations d'op�rations interm�diaires, qui permettent de modifier le comportement du flux de diff�rentes mani�res. Chacune de ces op�rations retourne un nouveau flux, mais ces derniers sont cr��s de mani�re lazy (paresseuse)�: aucun traitement n'est effectu� lors de leur d�claration.
  3. Un appel de l'op�ration terminale qui va fournir un r�sultat. C'est elle qui va d�clencher le parcours des donn�es et ex�cuter les diff�rentes op�rations interm�diaires.


Remarque : la manipulation du stream n'a aucun impact sur la source de donn�es, mais uniquement sur le r�sultat du stream.

Par exemple�:
Code Java : S�lectionner tout
1
2
3
IntStream.range(0, 10000)                    // 1. Cr�ation d'un Stream d'int allant de 0 � 10�000. 
    .filter(i -> i%2==0 && i%3==0 && i%5==0) // 2. Op�ration interm�diaire�: on n'accepte que les valeurs divisibles � la fois par 2, 3 et 5. 
    .forEach(System.out::println);           // 3. Op�ration finale�: on boucle sur les valeurs, pour les afficher avec System.out.println().

Mis � jour le 10 juillet 2015 adiGuba bouye

Non, il n'est pas possible de r�utiliser un flux. Les streams sont con�us pour �tre utilis�s via un cha�nage de m�thodes, et ils ne peuvent �tre utilis�s qu'une seule fois�: au moment auquel l'op�ration terminale est invoqu�e. Cependant, les op�rations terminales iterator() et spliterator() �chappent en partie � cette r�gle en diff�rant l�ex�cution des op�rations interm�diaires jusqu'au moment de la manipulation des it�rateurs retourn�s par ces m�thodes.

Mis � jour le 10 juillet 2015 adiGuba bouye

Il existe quatre types de flux�:

  • Stream - repr�sente les flux sur des objets�;
  • IntStream - repr�sente un flux sp�cialis� d'int�;
  • LongStream - repr�sente un flux sp�cialis� de long�;
  • DoubleStream - repr�sente un flux sp�cialis� de double.


Il est possible de passer d'un type de flux � un autre en invoquant des op�rations interm�diaires de conversion.

Mis � jour le 10 juillet 2015 adiGuba bouye

Il existe plusieurs mani�res de cr�er un stream�: on peut utiliser une source de donn�es pr�existante, ou m�me une m�thode qui nous g�n�rera les donn�es au fur et � mesure du parcours du flux (utile pour des flux ��infinis��).

Les streams basent leur fonctionnement sur des instances de la classe Spliterator, une sorte de super-it�rateur qui peut se d�couper en deux et conserve certaines caract�ristiques de la source de donn�es afin d'optimiser le traitement. En th�orie, il faudrait passer par les m�thodes statiques de la classe StreamSupport pour cr�er un Stream � partir d'un Spliterator. Heureusement, l'API standard nous offre plusieurs mani�res d'obtenir un flux, si bien qu'il sera rare d'avoir � utiliser le Spliterator.

En voici une liste non exhaustive�:

Code Java : S�lectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// Stream vide�: 
Stream.empty(); 
  
// Stream infini g�n�r� � partir de Math.random()�: 
Stream.generate(Math::random); 
  
// Stream � partir d'une liste de valeur 
Stream.of("a", "b", "c"); 
  
// Stream g�n�r� dynamiquement, repr�sentant les valeurs de 0 � 100 (compris ou pas) 
IntStream.rangeClosed(0, 100); 
IntStream.range(0, 100); 
  
// Stream repr�sentant la concat�nation de deux Streams�: 
IntStream.concat( 
    IntStream.range(0, 100),  
    IntStream.of(200, 300, 400, 500)); 
  
// Stream g�n�r� dynamiquement, repr�sentant les valeurs num�riques via un incr�ment de 0.5�: 
DoubleStream.iterate(0.0, n -> n + 0.5); 
  
// Stream g�n�r� � partir du contenu d'un tableau�: 
String[] array = { "a", "b", "c" }; 
Arrays.stream(array); 
  
// Stream g�n�r� � partir du contenu d'une collection (List, Set, ...)�: 
Collection<String> collection = Arrays.asList("a", "b", "c"); 
collection.stream(); 
// M�me chose, mais avec un Stream parall�le�: 
collection.parallelStream(); 
  
try (BufferedReader reader�: Files.newBufferedReader(Paths.get("in.txt"))) { 
    // Stream obtenu � partir des lignes du fichier�: 
    reader.lines(); 
}

L'utilisation la plus fr�quente consiste � invoquer la m�thode stream() de l'API de Collection, qui permet d'obtenir un Stream se basant sur le contenu de la collection en question.

Mis � jour le 6 juillet 2015 adiGuba

Une op�ration stateless (sans �tat) est un type d�op�rations interm�diaires qui ne g�re aucun �tat pendant le traitement du flux, ce qui permet de parall�liser les traitements sans trop de surco�ts. Ces op�rations se basent uniquement sur l'�l�ment courant du flux, ind�pendamment des autres �l�ments.

Cependant, il existe quelques op�rations interm�diaires dites stateful (litt�ralement ��pleine d��tat��) qui doivent g�rer un �tat pour effectuer correctement leur traitement (par exemple�: les op�rations skip(), limit(), distinct() et sorted()). Ces op�rations peuvent devenir tr�s co�teuses si on manipule un flux de donn�es � la fois ordonn� et en parall�le. Dans ce cas-l�, il peut �tre pr�f�rable d'utiliser un traitement s�quentiel (via l�op�ration sequential()) ou d'ignorer l'ordre des �l�ments (via l�op�ration unordered()), selon ce qui s'adapte le mieux � votre besoin.

Mis � jour le 10 juillet 2015 adiGuba

Une op�ration short-circuiting (court-circuitante) est une op�ration interm�diaire qui ne va pas obligatoirement traiter tous les �l�ments du flux. Par exemple, l�op�ration limit() va seulement traiter N �l�ments du flux. L�op�ration findFirst() va, quant � elle, arr�ter d�s qu'elle trouvera le premier �l�ment correspondant ; ce qui permet d'utiliser des streams infinis, sans boucler ind�finiment.

Mis � jour le 10 juillet 2015 adiGuba

Il est possible de convertir un flux d'un type A en un flux d'un type B en invoquant une des variantes de l�op�ration map() de ce flux. Cette op�ration est interm�diaire.

  • map() - permet de convertir un Stream<T> en Stream<V>�;
  • mapToDouble() - permet de convertir un Stream<T> en DoubleStream�;
  • mapToInt() - permet de convertir un Stream<T> en IntStream�;
  • mapToLong() - permet de convertir un Stream<T> en LongStream.


Par exemple�:

Code Java : S�lectionner tout
1
2
3
Stream<Client> fluxDeClient = [...] 
Stream<NumeroDeTelephone> fluxDeClient.map(client -> client.getNumeroDeTelephone()); 
IntStream fluxDAge = fluxDeClient.mapToInt(client -> client.getAge());

De plus, les flux de literals permettent d'obtenir des flux objet du type wrapper �quivalent en invoquant l�op�ration boxed() de ces flux. Cette op�ration est interm�diaire.

Par exemple�:

Code Java : S�lectionner tout
1
2
IntStream fluxLiteral = IntStream.range(0, 10); 
Stream<Integer> fluxWrapper = fluxLiteral.boxed();

Mis � jour le 22 juin 2015 bouye

Il est possible de convertir un flux en un type de stockage arbitraire en invoquant l�op�ration collect() de ce flux et en passant � cette op�ration une instance de la classe java.util.stream.Collector<T,A,R>. Cette op�ration est terminale.

Ici�:

  • T est le type des �l�ments du flux�;
  • A est un type interm�diaire g�n�ralement laiss� aux soins de l�impl�mentation de l�op�ration�;
  • R est le type r�sultat de l�op�ration (qui peut �tre autre chose qu'une collection).


L'API stream fournit de base la classe utilitaire java.util.stream.Collectors qui propose plusieurs m�thodes qui fournissent des collecteurs pr�ts � l'emploi pour convertir un flux en collections�:

  • toCollection() - permet la cr�ation d'une Collection<V> (collection arbitraire) � partir du flux de type Stream<T>�;
  • toConcurrentMap() - permet la cr�ation d'une ConcurrentMap<U, V> (dictionnaire disposant de m�thodes synchronis�es) � partir du flux de type Stream<T>�;
  • toList() - permet la cr�ation d'une List<T> (liste) � partir du flux de type Stream<T>�;
  • toMap() - permet la cr�ation d'une Map<U, V> (dictionnaire) � partir du flux de type Stream<T>�;
  • toSet() - permet la cr�ation d'un Set<T> (ensemble) � partir du flux de type Stream<T>.


Par exemple�:

Code Java : S�lectionner tout
1
2
3
4
5
6
7
8
9
10
11
List<Integer> listeDEntiers = IntStream.range(0, 10) 
    .boxed() 
    .collect(Collectors.toList()); 
[...] 
Stream<Client> fluxDeClients = [...] 
// Le premier param�tre du g�n�rateur sert � g�n�rer les cl�s de l'association�; tandis que le second param�tre sert � g�n�rer la valeur associ�e � cette cl�. 
// Ici, l'id du client sert de cl� dans l'association. 
// La valeur associ�e � cette cl� est le client lui-m�me. 
Map<Integer, Client> associationDeClients = fluxDeClients.collect(Collectors.toMap(client -> client.getId(), client -> client)); 
// Ou�: 
Map<Integer, Client> associationDeClients = fluxDeClients.collect(Collectors.toMap(client -> client.getId(), Functions.identity()));

Mis � jour le 22 juin 2015 bouye

Il est possible de convertir un flux en un tableau en invoquant une des variantes de l�op�ration toArray() de ce flux. Cette op�ration est terminale.

toArray()
Cette version de la m�thode, qui n'a pas d'argument, permet de g�n�rer un tableau d'objets (Object[]).

Par exemple�:

Code Java : S�lectionner tout
1
2
Stream<Client> fluxDeClients = [...] 
Object[] tableauDeClients = fluxDeClients.toArray();

toArray(generator)
Cette seconde version de la m�thode prend en param�tre un g�n�rateur de tableaux qui permet d'instancier un tableau � la taille requise. Elle renvoie un tableau du m�me type que les objets contenus dans le flux. Le g�n�rateur est une fonction qui prend un entier, la taille du tableau, en param�tre et renvoie un tableau de la taille et du type voulu. Ce g�n�rateur peut �tre, tout simplement, une r�f�rence de m�thode vers le constructeur de tableaux du type appropri�.

Par exemple�:

Code Java : S�lectionner tout
1
2
3
4
Stream<Client> fluxDeClients = [...] 
Client[] tableauDeClients = fluxDeClients.toArray(taille -> new Client[taille]); 
// Ou on donne une r�f�rence au constructeur de tableaux. 
Client[] tableauDeClients = fluxDeClients.toArray(Client[]::new);

Mis � jour le 22 juin 2015 bouye

Proposer une nouvelle r�ponse sur la FAQ

Ce n'est pas l'endroit pour poser des questions, allez plut�t sur le forum de la rubrique pour �a


R�ponse � la question

Liens sous la question
pr�c�dent sommaire suivant
 

Les sources pr�sent�es sur cette page sont libres de droits et vous pouvez les utiliser � votre convenance. Par contre, la page de pr�sentation constitue une �uvre intellectuelle prot�g�e par les droits d'auteur. Copyright � 2025 Developpez Developpez LLC. Tous droits r�serv�s Developpez LLC. Aucune reproduction, m�me partielle, ne peut �tre faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'� trois ans de prison et jusqu'� 300 000 � de dommages et int�r�ts.