POO Nouveautés 1.8 Stream Avant la version 8 de java, les traitements sur les collections passaient essentiellement par les itérateurs, exemple avant java 1.8 : Iterator<Taxi> it = taxis.iterator(); //taxis est une ArrayList<Taxi> Taxi tax; while(it.hasNext()){ tax = it.next(); if(tax.isFree()) return tax; } return null; //Retourne le premier taxi libre L’API (Application Programming Interface, ensemble normalisé de classes et methodes) java propose désormais un nouvel objet : « Stream ». - Ce dernier se construit à partir d’une source : collection, tableau, etc… - Un Stream ne stocke pas de données, il les transferts d’une source (collection) vers une suite d’opération. - Il ne modifie pas les données de la source, s’il en modifie pour les réutiliser il va créer un autre Stream. - Le chargement des données pour des opérations sur un Stream s’effectue de manière « lazy ». Ce qui permet d’optimiser les performances d’une application (recherche d’un pattern). - Un Stream peut ne pas être borné, cependant il faut faire attention à ce que les opérations se terminent dans un temps fini, avec des méthodes comme « limit(n) » ou « findFirst() ». - Un Stream n’est pas réutilisable, si on veut réutiliser des données de la source sur laquelle il a été construit il faudra en créer un nouveau. Création : La manière la plus courante de créer un Stream est d’appeler la méthode « stream() » (ou « parallelStream() ») sur une collection. Cependant il existe un certains nombres de méthodes comme « chars() » pour la classe String qui retourne un IntStream construit sur les différents caractères de la chaine, etc… Il est également possible de créer stream infini : Stream.iterate(1, x -> x*2) //Retourne un stream infini d’entiers contenant la suite des puissance de 2. Opérations intermédiaires et terminales : Les opérations intermédiaires sont effectuées de manière lazy et renvoie un nouveau stream, ce qui crée une succession de streams (nommés « stream pipelines »). Tant qu’aucune opération terminale ne sera appelée sur un stream pipeline, les opérations intermédiaires ne seront pas réellement effectuées. Les opérations terminales, elles, traversent tous les streams créés par les opérations intermédiaires, applique les opérations aux données puis l’opération terminale (fin). On dit que les streams sont alors consommés (ils sont détruits et inutilisables). Exemple équivalent après java 1.8 : return taxis.stream().filter(taxi -> taxi.isFree()).findFirst().get(); Création du stream Opération intermédiaire (filtre les taxis libres) Pour éviter les problèmes, on peut offrir une alternative : Opération terminale (prend le premier du filtre) Récupère l’objet return taxis.stream().filter(s -> s.isFree()).findFirst().orElse(null);