Académique Documents
Professionnel Documents
Culture Documents
JAVA
Deuxième année Informatique (ENICARTHAGE)
1
LES COLLECTIONS ET
LES STREAMS
2
GÉNÉRICITÉ
❖ En POO, la généricité est un concept permettant de définir des algorithmes (types de
données et méthodes) identiques qui peuvent être utilisés sur de multiples types de
données. Cela permet donc de réduire les quantités de codes à produire.
// exemple 1: ArrayList
import java.util.ArrayList;
import java.util.Date; Essai
public class Genericite { Cours Java
public static void main(String[] args) { Tutoriel Java
// création d'un tableau dynamique des instances de Object Thu Oct 06 14:10:04 GMT+01:00 2022
ArrayList collection = new ArrayList();
// On y stocke nos chaînes de caractères (possible par polymorphisme)
collection.add( "Essai" ); collection.add( "Cours Java" ); collection.add( "Tutoriel Java" );
// Mais rien nous interdit d'y mettre autre chose (polymorphisme)
collection.add( new Date() );
// Maintenant on parcourt la collection
for ( Object value : collection ) {
3
System.out.println( value ); }}}
// Si nous utilisons la généricité, nous pouvons indiquer que la collection ne peut contenir que des chaînes de caractères
ArrayList<String> collection = new ArrayList<String>();
7
// exemple:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
public enum Category { Ouvrier, Ingenieur, Directeur}
public class Employe {
private int id; private String name; private int age; private double salary; private Category cat;
public Employe(int id, String name, int age, double salary, Category cat) {
this.id = id; this.name = name; this.age = age; this.salary = salary; this.cat = cat; }
public int getId() { return id; }
public String getName() { return name; }
public int getAge() { return age; }
public double getSalary() { return salary; }
public Category getCategory(){ return cat; }
public void setId(int id) { this.id = id; }
public void setName(String name) { this.name= name; }
public void setAge(int age) { this.age = age; }
public void setSalary(double salary ) { this.salary=salary; }
public void setCategory(Category cat) { this.cat=cat; }
8
@Override
public String toString() {
return "[id=" + this.id + ", name=" + this.name + ", age=" + this.age + ", salary=" + this.salary + " Category: "+this.cat+ "]";
}}
public class LesCollections {
public static void main(String[] args) {
// tableaux statiques collections
System.out.println("---------------- Array -------------------");
Employe[] employes1 = {new Employe(0,"Ferid", 25, 2000.0, Category.Ingenieur), new Employe(1,"Samia", 30, 3000.1,
Category.Directeur)};
Employe[] employes2 =new Employe[2];
employes2[0] = new Employe(0,"Ferid", 25, 2000.0, Category.Ingenieur);
employes2[1] = new Employe(1,"Samia", 30, 3000.1, Category.Directeur);
System.out.println("affichage du contenu tableau statique");
for (Employe emp:employes2){
System.out.println(emp); }
// tableaux dynamiques
System.out.println("---------------- ArrayList-------------------");
List<Employe> employeList = new ArrayList<Employe>();
employeList.add(new Employe(0,"Ferid", 25, 2000.0, Category.Ingenieur));
employeList.add(0, new Employe(1,"Samia", 30, 3000.1, Category.Directeur));
System.out.println("affichage du contenu ArrayList");
for (Employe emp:employeList){
System.out.println(emp); } 9
// listes chainées
System.out.println("---------------- LinkedList -------------------");
List<Employe> employeList1 = new LinkedList<Employe>();
employeList1.add(new Employe(0,"Ferid", 25, 2000.0, Category.Ingenieur));
employeList1.set(0, new Employe(1,"Samia", 30, 3000.1, Category.Directeur));
System.out.println("affichage du contenu LinkedList");
for (Employe emp:employeList1){ System.out.println(emp); }
// Emsembles
System.out.println("---------------- Set -------------------");
Set<String> se = new HashSet<String>() ;
se.add("un"); se.add("deux") ; se.add("un") ;
System.out.println("Taille du set : " + se.size()) ;
System.out.println("affichage du contenu Set");
for (String emp:se){ System.out.println(emp); }
// tables associatives
System.out.println("---------------- Map-------------------");
Map <String,Employe> m = new HashMap(); int i=0;
m.put("c", new Employe(i,"Salah", 30, 600.25, Category.Ouvrier));
m.put("f", new Employe(i++,"Said", 27, 600.25, Category.Ouvrier));
m.put("k", new Employe(i++,"Fethi", 32, 600.25, Category.Ouvrier));
m.put("P", new Employe(i++,"Nabiha",29 , 1500.0, Category.Ingenieur));
System.out.println("valeur associée à f est: "+m.get("f"));
System.out.println("liste des valeurs "+ m.values());
System.out.println("liste des clés: "+m.keySet());}} 10
---------------- Array -------------------
affichage du contenu tableau statique
[id=0, name=Ferid, age=25, salary=2000.0 Category: Ingenieur]
[id=1, name=Samia, age=30, salary=3000.1 Category: Directeur]
---------------- ArrayList-------------------
affichage du contenu ArrayList
[id=1, name=Samia, age=30, salary=3000.1 Category: Directeur]
[id=0, name=Ferid, age=25, salary=2000.0 Category: Ingenieur]
---------------- LinkedList -------------------
affichage du contenu LinkedList
[id=1, name=Samia, age=30, salary=3000.1 Category: Directeur]
---------------- Set -------------------
Taille du set : 2
affichage du contenu Set
un
deux
---------------- Map-------------------
valeur associée à f est: [id=0, name=Said, age=27, salary=600.25 Category: Ouvrier]
liste des valeurs [[id=2, name=Nabiha, age=29, salary=1500.0 Category: Ingenieur], [id=0, name=Salah, age=30,
salary=600.25 Category: Ouvrier], [id=0, name=Said, age=27, salary=600.25 Category: Ouvrier], [id=1,
name=Fethi, age=32, salary=600.25 Category: Ouvrier]]
liste des clés: [P, c, f, k]
11
Il existe une autre façon pour créer des listes en utilisant la méthode statique asList() de la
classe Arrays. Rappelons que cette classe comporte un ensemble de méthodes statiques qui
s’appliquent sur des tableaux.
// continuons avec le même exemple:
// autre façon de créer des listes avec méthodes statique de Arrays
System.out.println("---------------- liste avec Arrays -------------------");
List<Employe> employes3 = Arrays.asList(new Employe(i,"Salah", 30, 600.25, Category.Ouvrier),new
Employe(i++,"Said", 27, 600.25, Category.Ouvrier));
for (Employe emp:employes3){
System.out.println(emp); }
12
CLASSE COLLECTIONS
Classe identique à la classe Arrays avec des méthodes statiques qui s’applique sur des
collections:
Tri: sort(List list) ; sort(List list,Comparator comp)
Mélange aléatoire: shuffle(List liste) ;
Manipulations: reverse(List liste) ; fill (List liste, Object element) ; copy(List dest, List src) ;
Recherche binaire: binarySearch(List list, Object element) ;
// continuons avec le même exemple:
// test des méthodes statiques de Collections
System.out.println("---------------- classe Collections -------------------");
List<Integer> entiers = Arrays.asList(12,45,10,-5,56);
yetbadlou fil list entiers , tsirlou tri
Collections.sort(entiers);
13
for (Integer emp:entiers){
System.out.print(emp+" "); }
System.out.println();
System.out.println(Collections.binarySearch(entiers, 45));
System.out.println(Collections.binarySearch(entiers, 6));
List<String> chaines = Arrays.asList("Ali","Enicar","Car","Bac");
Collections.sort(chaines);
for (String emp:chaines){
---------------- classe Collections -------------------
System.out.print(emp+" "); }
-5 10 12 45 56
System.out.println();
3
System.out.println(Collections.max(chaines));
-2
}
Ali Bac Car Enicar
Enicar
// Comment faire le tri/chercher les bornes (…) d’une collection des employés?
14
LES INTERFACES DE
COMPARAISON
❖ Java propose l’interface générique Comparable <T> qui doit être implémentée par une classe
si nous voulons utiliser les méthodes de tri d’Arrays ou Collections. Elle possède une seule
méthode int compareTo(T obj)
✔ retourne un entier négatif si l’objet qui fait l’appel est plus petit que obj
✔ nul (égal) si ils sont identiques,
✔ ou a positif (supérieur) si il est plus grand
❖ L’interface générique Comparator <T> propose une méthode int compare(Object o1, Object
o2). Celle-ci retourne un entier négatif, nul ou positif si le premier objet est respectivement
inférieur, égal ou supérieur au deuxième
15
// Modifions le même exemple:
public class Employe implements Comparable<Employe> { // mêmes attributs et méthodes
@Override
public int compareTo(Employe o) {
return (this.age-o.age); } }
// dans la classe principale
List<Employe> employes4 = Arrays.asList(new Employe(0,"Salah", 30, 600.25,
Category.Ouvrier),new Employe(1,"Said", 27, 600.25, Category.Ouvrier));
System.out.println("-----------tri avec Comparable -------");
System.out.println("liste avant le tri");
for (Employe emp:employes4){ -----------tri avec Comparable -------
System.out.println(emp); } liste avant le tri
Collections.sort(employes4); [id=0, name=Salah, age=30, salary=600.25 Category: Ouvrier]
System.out.println("liste après le tri"); [id=1, name=Said, age=27, salary=600.25 Category: Ouvrier]
for (Employe emp:employes4){ liste après le tri
System.out.println(emp); } [id=1, name=Said, age=27, salary=600.25 Category: Ouvrier]
[id=0, name=Salah, age=30, salary=600.25 Category: Ouvrier]
16
// Modifions le même exemple: avec l’interface fonctionnelle Comparator
// dans la classe principale
List<Employe> employes5 = Arrays.asList(new Employe(0,"Salah", 30, 600.25, Category.Ouvrier),new Employe(1,"Said",
27, 1000.25, Category.Ouvrier));
System.out.println("-----------tri avec Comparator -------");
System.out.println("liste avant le tri");
for (Employe emp:employes5){
System.out.println(emp); }
Collections.sort(employes5, (o1,o2)->o1.getAge()-o2.getAge());
System.out.println("liste après le tri d'age");
for (Employe emp:employes5){
System.out.println(emp); }
Collections.sort(employes5, (o1,o2)->(int)(o1.getSalary()-o2.getSalary()));
System.out.println("liste après le tri de salaire");
for (Employe emp:employes5){ -----------tri avec Comparator -------
System.out.println(emp); } liste avant le tri
[id=0, name=Salah, age=30, salary=600.25 Category: Ouvrier]
[id=1, name=Said, age=27, salary=1000.25 Category: Ouvrier]
liste après le tri d'age
[id=1, name=Said, age=27, salary=1000.25 Category: Ouvrier]
[id=0, name=Salah, age=30, salary=600.25 Category: Ouvrier]
liste après le tri de salaire
[id=0, name=Salah, age=30, salary=600.25 Category: Ouvrier]
[id=1, name=Said, age=27, salary=1000.25 Category: Ouvrier]
17
AUTRES INTERFACES
FONCTIONNELLES GÉNÉRIQUES
❖ public interface Consumer <T> { UTILES
void accept(T); }
❖ Parmi les méthodes des collections d’un type T: forEach (Consumer<? Super T>)
// exemple d’utilisation
List <Employe> employes5 = Arrays.asList(new Employe(0,"Salah", 30, 600.25, Category.Ouvrier),new
Employe(1,"Said", 27, 1000.25, Category.Ouvrier));
// au lien de: for (Employe emp:employes5) { System.out.println(emp); }
// en utilisant les expressions Lambda
employes5.forEach((Employe e) -> System.out.println(e));
// en utilisant reference au méthode:
employes5.forEach(System.out::println);
18
❖ public interface Supplier <T> { T get(); }
❖ public interface Predicate <T> { boolean test(T); }
❖ public interface Function <T1, T2> { T2 apply(T1); }
// exemple d’utilisation
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
public class InterfacesUtiles { 120.0
Suceess
public static void main(String[] args) {
true
Function <Integer,Double> fun = i->i*10.0; System.out.println(fun.apply(12));
Supplier <String> supp = ()-> "Suceess"; System.out.println(supp.get());
Predicate <Double> pre = n-> n<20; System.out.println(pre.test(15.0));}}
21
MÉTHODES DES STREAMS
Méthodes de création à partir des collections: stream() et/ou parallel()
22
Méthodes intermédiaires
23
// exemple :
List<Integer> liste = new ArrayList<>();
liste.add(12);liste.add(45);liste.add(-5);liste.add(56); 12
Stream <Integer> str = liste.stream(); 45
Stream <Integer> str1 = str.filter(e->e>0); 56
str1.forEach(System.out::println); cachalot
// ou en une seule ligne chameau
liste.stream().filter(e->e>0).forEach(System.out::println); Chat
3.0
List<String> strings = Arrays.asList("girafe", "chameau", "chat", "poisson", "cachalot"); 9.0
strings.stream().filter(x -> x.contains("cha")).sorted().forEach(System.out::println);
LinkedList <Point> points = new LinkedList();
points.add(new Point(-2,5));
points.add(new Point(7,2));
points.stream().map(p-> p.getX()+p.getY()).forEach(System.out::println);
maptoDouble
Autres formes de map maptoInt
maptoLong
24
System.out.println("tri selon ordonnée croissante"); tri selon ordonnée croissante
points.stream().sorted((p1,p2)->(int)(p1.getY()-p2.getY())).forEach(System.out::println); Point: (7.0,2.0 )
Point: (-2.0,5.0 )
Méthodes terminales:
✔ collect(méthode statique de
public record Commande(String nom, double prix, Client client)
Collectors): {}
public class TerminalesStreams {
La collecte permet de créer un nouvelle collection public static void main(String[] args) {
à partir d’un stream List<Commande> mesCommandes = Arrays.asList(new
// exemple: Commande("Stylos",5.0,new Client(78945689,"Ali")),new
public class Client { Commande("Cartbale",20.5,new Client(78941789,"Samia")), new
private int rip; private String nom; Commande("feuilles",7.2,new Client(78945689,"Ali")));
public Client(int rip, String nom){ List<Client> mesClients = mesCommandes.stream().map( c ->
this.rip = rip; this.nom = nom; } c.client()).collect( Collectors.toList() );
public int getRip(){return rip;} mesClients.forEach(System.out::println);
public String getNom(){return nom;} double chiffreAffaire = mesCommandes.stream().collect(
public void setRip(int rip){this.rip = rip;} Collectors.summingDouble( Commande::prix ) );
public void setNom(String nom){this.nom = nom;} System.out.println(chiffreAffaire); }}
@Override
public String toString(){ Nom du client = Ali de rip: 78945689
return "Nom du client = "+nom+" de rip: "+rip;} Nom du client = Samia de rip: 78941789
@Override Nom du client = Ali de rip: 78945689
public boolean equals(Object o){ 32.7
25
Client cl = (Client)o;
Quelques méthodes statiques de Collectors: toList(), toSet(), summingDouble(),
summingInt(), joining(), groupingBy()…
// continuons l’exemple:
String joined = mesCommandes.stream().map(Commande::toString).collect(Collectors.joining(","));
System.out.println(joined);
Stylos
Cartbale
feuilles
[Commande[nom=Stylos, prix=5.0, client=Nom du client = Ali de rip: 78945689]]
[Commande[nom=Cartbale, prix=20.5, client=Nom du client = Samia de rip: 78941789]]
[Commande[nom=feuilles, prix=7.2, client=Nom du client = Ali de rip: 78945689]]
26
✔ La réduction
La réduction consiste à obtenir un résultat unique à partir d’un stream. Les réductions simples sont celles
auxquelles on pourrait penser en premier lieu : La somme d’éléments (Stream.sum), le maximum
(Stream.max), ou le nombre d’éléments (Stream.count) sont des réductions simples
// continuons l’exemple:
OptionalDouble moy = mesCommandes.stream().mapToDouble(c->c.prix()).average();
System.out.println(moy); OptionalDouble[10.9]
OptionalDouble maximum = mesCommandes.stream().mapToDouble(c->c.prix()).max(); OptionalDouble[20.5]
System.out.println(maximum); OptionalDouble[5.0]
OptionalDouble minimum = mesCommandes.stream().mapToDouble(c->c.prix()).min(); 3
System.out.println(minimum);
Long nbr = mesCommandes.stream().mapToDouble(c->c.prix()).count();
System.out.println(nbr);
Stream.iterate(5,i->i*10)
// Pour exécuter l’exemple traité sur les streams vous avez besoin des ces importations:
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.OptionalDouble;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
29