0% ont trouvé ce document utile (0 vote)
6 vues17 pages

Introduction aux Streams en Java 8

Transféré par

salma ben hssin
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
6 vues17 pages

Introduction aux Streams en Java 8

Transféré par

salma ben hssin
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

COURS JAVA

AVANCÉ
PARTIE 2 - SUITE
Mme Nouira Sana
COURS JAVA AVANCÉ -

LES STREAMS
Mme Nouira Sana
API STREAM : UNE NOUVELLE FAÇON DE GÉRER LES COLLECTIONS EN JAVA 8

 Cette nouvelle API fournie par le JDK 8 modifier


fondamentalement notre façon de traiter les
Collections.
 Elle propose une alternative au pattern Iterator
relativement lourd à mettre en place.
 Celle-ci tire profit de la nouvelle syntaxe des lambdas
expressions pour réduire le code un maximum tout en
améliorant ses performances.
 De plus, la classe Collectors offre de nombreux
patterns qui remplacent dans de nombreux cas le
pattern Iterator.
QU’EST-CE QU’UN STREAM ?
 Un Stream n’est pas une collection ou une structure de
donnée de manière générale.
 C’est une séquence d’éléments sur laquelle on peut
effectuer un groupe d’opérations de manière séquentielle ou
parallèle.

public interface Stream<T>

Permet de remplacer le pattern Iterator

 Il existe deux types d’opérations sur les Stream :


 Les opérations intermédiaires : elles transforment un Stream
en autre Stream : ce genre d’opération conserve le stream
ouvert ce qui permet d’effectuer d’autre opérations dessus.
Exemple : Methodes map() et filter()
 Les opérations finales (terminale): elles produisent un résultat
ou un « side-effect » . C’est l’opération finale du stream, c’est ce
qui lance la « consommation » du stream. Exemple : Reduce()
[Link]
 Les streams utilisent les interfaces fonctionnelles

 un Stream ne stocke aucune donnée il se contente de


les transférer vers une suite instruction à opérer

 Un stream ne modifie pas les données

 Un stream est à usage unique : une fois utilisé


complètement impossible de l’utiliser une seconde
fois
EXEMPLE CLASS TESTSTREAM (VOIR NETBEANS)
public enum Couleur { public class Personne {
MARRON("marron"), public Double taille = 0.0d, poids = 0.0d;
BLEU("bleu"), public String nom = "", prenom = "";
VERT("vert"), public Couleur yeux = [Link];
VERRON("verron"), public Personne() { }
public Personne(double taille, double poids, String nom, String prenom, Couleur yeux)
INCONNU("non déterminé"), {
ROUGE("rouge mais j'avais piscine..."); super();
[Link] = taille; [Link] = poids;
private String name = ""; [Link] = nom; [Link] = prenom;
Couleur(String n){name = n;} [Link] = yeux; }
public String toString()
{return name;} public String toString() {
} String s = "Je m'appelle " + nom + " " + prenom;
s += ", je pèse " + poids + " Kg";
s += ", et je mesure " + taille + " cm.";
return s;
}
// getter et setter ….}}
public class TestStream {
public static void main(String[] args) {
List<Personne> listP = [Link](
new Personne(1.80, 70, "A", "Noura", [Link]),
new Personne(1.56, 50, "B", "Nouira", [Link]),
new Personne(1.75, 65, "C", "Ali", [Link]),
new Personne(1.68, 50, "D", "Sonia", [Link]),
new Personne(1.96, 65, "E", "Karima", [Link]),
new Personne(2.10, 120, "F", "Emna", [Link]),
new Personne(1.90, 90, "G", "Skander", [Link]) );
//parcours stream
Je m'appelle A Noura, je pèse 70.0 Kg, et je mesure 1.8 cm.
Stream<Personne> sp = [Link](); Je m'appelle B Nouira, je pèse 50.0 Kg, et je mesure 1.56 cm.
Je m'appelle C Ali, je pèse 65.0 Kg, et je mesure 1.75 cm.
[Link]([Link]::println); Je m'appelle D Sonia, je pèse 50.0 Kg, et je mesure 1.68 cm.
Je m'appelle E Karima, je pèse 65.0 Kg, et je mesure 1.96 cm.
Je m'appelle F Emna, je pèse 120.0 Kg, et je mesure 2.1 cm.
Je m'appelle G Skander, je pèse 90.0 Kg, et je mesure 1.9 cm.
// operation Filter
[Link]("\nAprès le filtre filtrer personne dont poids est >50");
sp = [Link](); //N'oubliez surtout pas de recréer le stream car le premier est entièrement consommé
[Link](x -> [Link]() > 50).forEach([Link]::println);
Après le filtre
Je m'appelle A Noura, je pèse 70.0 Kg, et je mesure 1.8 cm.
Je m'appelle C Ali, je pèse 65.0 Kg, et je mesure 1.75 cm.
Je m'appelle E Karima, je pèse 65.0 Kg, et je mesure 1.96 cm.
Je m'appelle F Emna, je pèse 120.0 Kg, et je mesure 2.1 cm.
Je m'appelle G Skander, je pèse 90.0 Kg, et je mesure 1.9 cm., et je mesure 1.9 cm.
//Operation map
//appliquer une opération sur chaque élément afin de ne récupérer que ce qui nous intéresse.
//Par exemple, en ne conservant que le poids des personnes que nous avons filtré.

[Link]("\nAprès le filtre et le map");


sp = [Link]();
Après le filtre et le map
[Link](x -> [Link]() > 50) 70.0
.map(x -> [Link]()) 65.0
65.0
.forEach([Link]::println); 120.0
90.0
//operation reduce
//Cette opération a pour but d'agréger le contenu de votre stream pour fournir un résultat unique.
//Exemple calculer la somme des poids des personnes que nous //avons filtré précédemment

[Link]("\nAprès le filtre et le map et reduce");


sp = [Link]();
Double sum = [Link](x -> [Link]() > 50)
.map(x -> [Link]())
Après le filtre et le map et reduce
.reduce(0.0d, (x,y) -> x+y);
410.0
[Link](sum);
[Link]("\nAprès le filtre et le map et reduce");
sp = [Link]();
Optional<Double> sum = [Link](x -> [Link]() > 250)
.map(x -> [Link]())
.reduce((x,y) -> x+y);
if([Link]())
[Link]([Link]()); Après le filtre et le map et reduce
Aucun aggrégat de poids...
else
[Link]("Aucun aggrégat de poids...");
sp = [Link]();
long count = [Link](x -> [Link]() > 50)
.map(x -> [Link]())
.count(); Nombre d'éléments : 5

[Link]("Nombre d'éléments : " + count);

sp = [Link]();
List<Double> ld = [Link](x -> [Link]() > 50)
.map(x -> [Link]())
.collect([Link]());
[70.0, 65.0, 65.0, 120.0, 90.0]
[Link](ld);
EXEMPLE ORDER( NETBEANS)
 Manipuler des ordres d’achats et de ventes de produits.
Un ordre sera soit d’achat ou de vente d’un produit
quelconque (mobile, souris, vélo,…) avec un prix donné.
 Nous avons donc un objet Order qui définit quatre
propriétés.
 L’exercice consiste à récupérer dans la liste ci-dessous
les produits vendus et les trier par prix croissant.
import [Link];
import [Link];
import [Link];
import [Link]; •// Récupération de la liste triée sans l’utilisation des Stream
import static [Link]; List<Order> sellOrderList = new ArrayList<>();
public class Order { for (Order order : orderList) {
public enum OrderType { BUY, SELL };
if ([Link]() == [Link])
int id;
OrderType type; { [Link](order); }
Double price; }
String product; }
public Order(int id, OrderType type, Double price, String product) {
[Link] = id;
[Link] = type; [Link](sellOrderList, (o1, o2) ->[Link]().compareTo([Link]()));
[Link] = price; List<String> products = new ArrayList<>();
[Link] = product; for (Order o : sellOrderList) {
} [Link]([Link]());
public int getId() {return id; } [Link]([Link]());
public OrderType getType() { return type; } }
public Double getPrice() { return price; }
//*Resultat :
public String getProduct() { return product; }
keyboard
public String toString(){ return id +" "+ type + " " +price+ " " + product; }
mouse
public static void main(String[] args) {
bike*/ )
List<Order> orderList = new ArrayList<>();
.

[Link](new Order(1, [Link], 100.0, "phone"));


•//Récupération de la liste triée avec l’utilisation de Stream
[Link](new Order(2, [Link], 50.0, "mouse"));
List<String> products2 = [Link]()
[Link](new Order(3, [Link], 150.0, "bike"));
[Link](new Order(4, [Link], 500.0, "laptop")); .filter(o-> [Link]()==[Link])
[Link](new Order(5, [Link], 40.0, "keyboard")); .sorted([Link](Order::getPrice))
.map(Order::getProduct
.collect(toList());
[Link](products2);
•[Link]() renvoie un stream
//Resultat
d’objets Order soit Stream
[keyboard, mouse, bike]
}
AVEC STREAM :
 ArrayList temporaire disparait
 L’application d’operations successives sur la liste est
plus claire
 Le code se réduit à une ligne

•filter() permet de sélectionner dans le stream tous les éléments respectant un prédicat, en retour on obtient
toujours un Stream. C’est une fonction intermédiaire.

utilisation de la lambda o-> [Link]()==[Link]. Appliquée à chaque élément du Stream,


elle vérifiera le type de l’ordre. Ici par exemple nous souhaitons ne sélectionner que les ordres de vente.

•sorted() va trier les éléments du Stream en utilisant un comparator passé en argument, ici encore j’ai fait le choix
d’utiliser une lambda:
(o1, o2) -> [Link]().compareTo([Link]())
•.map() est bien connue en programmation fonctionnelle , elle va appliquer une transformation à chaque élément,
ici on va récupérer le produit sur lequel porte un ordre et ainsi récupérer en retour un stream de produits, Stream.
D’AUTRES OPÉRATIONS

 Peek : operation intermediaire permettant de «


déboguer » entre chaque opération.

 Limit ou skip :opération également intermédiaire


permettant de limiter ou bloquer des éléments
d'un stream.

 findFirst, findAny : opérations terminales qui


permet de trouver des éléments particuliers d'un
stream
public class ProjetStreams1 {

public static void main(String[] args) {


// interfaces fonctionnelles utiles
Function <Integer,Double> fun = new Function <Integer,Double> (){ public Double apply (Integer i){return i*10.0;} };
Consumer <String> cons = new Consumer <String> (){ public void accept (String s){[Link](s+" is consumed");} };
Supplier <String> supp = new Supplier <String> (){ public String get(){return "Success";} };
Predicate <Double> pre = new Predicate <Double> (){ public boolean test (Double n){return n<20;} };

// écriture par expressions Lambda


Function <Integer,Double> fun1 = i->i*10.0;
Consumer <String> cons1 = s->[Link](s+" is consumed");
Supplier <String> supp1 = ()-> "Suceess";
Predicate <Double> pre1 = n-> n<20;

// création de d'une liste avant Java 9


List <String> liste = new ArrayList(); Camion
[Link]("Camion");[Link]("voiture"); [Link]("train"); Voiture
[Link]([Link]::println); train
// en une seule instruction Camion
[Link]("Camion","voiture","train").forEach([Link]::println);
voiture
// autres collecions Train
Map <Integer,String> map = new HashMap();
[Link](1,"Camion"); [Link](2,"voiture"); [Link](3,"train"); 1=Camion
[Link]().forEach([Link]::println); 2=voiture
3=train
// interface fonctionnelle UnaryOperator
UnaryOperator<Integer> operator = t -> t * 2; 10
[Link]([Link](5)); 20
[Link]([Link](10));
30
[Link]([Link](15));
UnaryOperator<Integer> operator1 = t -> t + 10;
UnaryOperator<Integer> operator2 = t -> t * 10;
int a = [Link](operator2).apply(5); 150
[Link](a); 60
int b = [Link](operator2).apply(5);
[Link](b);
// autres
DoubleBinaryOperator operator3 = (p, q) -> (p + q); 11.0
[Link]([Link](5, 6));
// Il existe des interfaces fonctionnelles spécifiques au Java 8:
// LongUnaryOperator, LongToIntFunction, IntSupplier, DoubleConsumer,
// IntToDoubleFunction, LongPredicate
}
}
public class ProjetStreams2 {

public static void main(String[] args) {


Stream <Integer> str = [Link] (3,9,7,5,1);
str. forEach (e->[Link](e+ " ")); // 3 9 7 5 1

IntStream str1 = [Link](4,3,2,9,4);


[Link](e-> [Link](e+" ")); //4 3 2 9 4

// generate (Supplier <T> s)


[Link](()-> "bonjour "); // Stream infini de String (bonjour)
[Link](Math::random); // Stream infini
[Link](Math::random).limit(8).forEach(e-> [Link](e+" "));
// 0.9779699305994837 0.7703551433855831 0.6167040553120374 0.7910158538290651
// 0.8796445810342365 0.3634712383918377 0.9174521161507594 0.9529296661567758
// iterate (T seed, UnaryOperator <T> f)
[Link](5,(e-> e+2)).limit(10).forEach(e-> [Link](e+" "));
// 5 7 9 11 13 15 17 19 21 23
[Link](20,23).forEach(e-> [Link](e+" "));
// 20 21 22

[Link](20,23).forEach(e-> [Link](e+" "));


//20 21 22 23

}}

Vous aimerez peut-être aussi