Vous êtes sur la page 1sur 40

Chapitre5: Collection

Dr. MALKI Abdelhamid


a.malki@esi-sba.dz
Ecole Nationale Supérieure d’Informatique de Sidi Bel Abbes (ENSI)
2015/2016
Collection: Définition
 Une collection est un objet qui contient(stocke) d'autres
objets de même nature (e.g.; l’ensemble des étudiants, liste
des produits achetés).

 Ces objets collection proposent une solution au


stockage de données et permettent une manipulation
de celles-ci (ajouter, supprimer, rechercher, trier, etc).
  
 Ils sont dynamiques : ils n'ont pas de taille prédéfinie
(contrairement aux tableaux)

 Le JDK fournit différents types de collections sous la forme


de classes et d’interfaces (le paquetage java.util)
Hiérarchie des interfaces
 Des interfaces dans 2 hiérarchies d’héritage principales :Collection
et Map •
 Collection <E> le type le plus général des collections. Définit un
groupe d'objets où la duplication peut-être autorisée.

 Map <K,V> correspond aux collections où les objets de type V


sont indexés par des clés de type K
Collection

Map
Set List Queue

SortedMap
SortedSet
NavigableMap
NavigableSet
Collection<E>

 une collection est un regroupement d’objets (ses éléments).

 on trouve des collections de comportements différents (listes,


ensembles, file.)

 une interface java.util.Collection<E> définit le contrat des


collections.

 à partir de java 1.5, les collections sont typées. Collection<E>


où E représente le type des éléments de la collection
(Collection<Etudiant> une collection d’etudiants)

 Aucune classe du JDK n’implante directement cette interface


(les collections vont implanter des sous-interfaces de
Collection, par exemple List, set, Queue)
Méthodes principales de Collection<E>
 boolean add(E e) : ajouter un élément
 boolean addAll(Collection) : ajouter plusieurs éléments
 void clear() : tout supprimer
 boolean contains(Object e) : test d'appartenance
 boolean containsAll(Collection) : appartenance collective
 boolean isEmpty() : test de l'absence d'éléments
 Iterator iterator() : pour le parcours (cf Iterator)
 boolean remove(Object e) : retrait d'un élément
 boolean removeAll(Collection) : retrait de plusieurs éléments
 boolean retainAll(Collection) : intersection
 int size() : nombre d'éléments
 E[] toArray() : transformation en tableau
 E[] toArray(E[] a) : tableau de même type que a
 Iterator<E> iterator(); // un itérateur sur la collection
List<E>
 suite ordonnée d’éléments (i.e. il existe un suivant et un
précédent)
 de taille non bornée
 qui supporte les opérations :
◦ rechercher
◦ supprimer
◦ ajouter en tête (insérer après/avant un élément, en fin)

Collection

Set List Queue

ArrayList LinkedList
List<E>

 interface List<E> = collection ordonnée d’objets


 2 classes implantant la sous-interface List<E>

 ArrayList<E> liste implémentée à l'aide d'un tableau redimensionnable


dont on peut fixer la capacité initiale.
 – Efficace pour get,set, add (temps « constant amorti »)
 – Coûteux d'ajouter/supprimer un élément au milieu de la liste

 LinkedList<E> implémentation avec une liste doublement chainée


 – insertion/suppression d'un élément efficace
 – Accès séquentiel plus coûteux (temps linéaire)
List<E>:Méthodes complémentaires
 Dans une liste les éléments sont ordonnés, la notion de position a un
sens.
 add(int index, E element) ajout de l’élément à l’index-ième position
 E get(int index) fournit l’index-ième élément de la liste.
IndexOutOfBoundsException - si (index < 0 || index >= size())
 E set(int index, E element) modifie l’index-ième élément de la liste
 E remove(int index) supprime l’index-ième élément de la liste. (même
exception)
 int indexOf(Object element) indice de la première occurrence element
dans la liste, -1 si absent
 int lastIndexOf(Object o) : dernier index de o dans la liste
 List<E> subList(int from, int to) : liste des éléments [from..to[
 ListIterator<E> listIterator(int i) : itérateur initialisé à l’index i
 ListIterator<E> itérateur pour listes doublement chaînées

 On peut évidemment utiliser toutes les méthodes héritées de l’interface


Collection : add (E), remove(Object), …etc.
La classe ArrayList
 Une instance de la classe ArrayList<E> est une sorte de tableau qui
peut contenir un nombre quelconque d’instances d’une classe E
 C’est un tableau redimensionnable dont la taille croit lorsque des
éléments sont ajoutés.
 Les emplacements sont indexés par des nombres entiers (à partir
de 0)
 Constructeurs
 ArrayList()
 ArrayList(int taille initiale) : peut être utile si on connaît la taille
finale ou initiale (après les premiers ajouts) la plus probable car
évite les opérations d’augmentation de la taille du tableau sous-
jacent
 ArrayList(Collection<? extends E> c) : pour l’interopérabilité entre
les différents types de collections
Exemple de ArrayList<E>
 ArrayList<String> L=new ArrayList<String>()
aa bb
 L.add("aa"); L.add("bb"); //ajouter à la fin
 L.add(1, "cc"); //ajouter à la 1ére position aa cc bb
 L.set(2, "dd"); //modifier le 2éme position aa cc dd
 L.remove(0) //supprimer le premier élément de la liste cc dd
 System.out.println(L);

 List<String> L2=new ArrayList<String>() //polymorphisme


 un objet (ArryListe<String>) dont la référence est une interface
(List<String>)
 On ne peut pas affecter L2 à une référence de type ArrayList<String>
 L2=L (correcte)
 L=L2 (erreur de compilation)  L=( ArrayList<String>) L2
Parcourir une Liste :solution naïve
 For (int i=0; i<L.size(); i++)
 //opération sur le iéme élément de la liste

 Exemple: ArrayList<String> L=new ArrayList<String>()


 L.add("aa"); L.add("bb"); L.add("cc");

 For (int i=0; i<L.size(); i++)


 System.out.println( L.get(i) ); aa bb cc

 For (int i=0; i<L.size(); i++){


 L.set(i, L.get(i)+"f");
 System.out.println( L.get(i) ); aaf bbf ccf
 }

 Une solution à éviter parce qu’elle est coûteuse en temps


d’exécution
Parcourir une Liste: Iterator<E>
 Cette interface définit des méthodes pour des objets capables de
parcourir les données d'une collection(parcours unidirectionnel):

 boolean hasNext(): indique s'il reste au moins un élément à


parcourir dans la collection

 E next(): renvoie l'élément courant dans le parcours et passe


l'itérateur à l'élément suivant

 ListIterator<E> parcours (bidirectionnel ) avant/arriére


(previous(), hasPrevious())

 + add(E e), set(E e)


Exemple : Iterator<E>
 ArrayList<String> L=new ArrayList<String>()
 L.add("aa"); L.add("bb"); L.add("cc");
 Iterator<String> it = L.iterator();
 while(it.hasNext()) aa bb cc
 System.out.println(it.next() );

 ListIterator<String> itd = L.listIterator();


 while(itd.hasNext()) {
 String x=itd.next();
 If(x.equals("bb")) itd.add("ee");
 }

 itd = L.listIterator();
 while(itd.hasNext())
 System.out.println(itd.next() ); aa bb ee cc
Parcourir une Liste :Foreach
 Une autre alternative pour l'itération sur des
structures.
 Syntaxe : for(Type var : Objet)

 for(String s : L)
 System.out.println(s);

 for(Etudiant e : L){
 System.out.println(e.nom);
LinkedList<E>
 Elle représente une liste doublement chaînée.
 Constructeurs:
 un constructeur sans paramètre
 un qui demande une collection. Dans ce cas, la liste sera initialisée
avec les éléments de la collection fournie en paramètre.
 Méthodes: Plusieurs méthodes pour ajouter, supprimer ou obtenir le
premier ou le dernier élément de la liste permettent d'utiliser cette
classe pour gérer une pile ou une file :
 void addFirst(E e): Ajoute un élément en début de liste.
 void addLast(E e): Ajoute un élément en fin de liste.
 E getFirst(): Retourne l'élément en début de liste.
 E getLast(): Retourne l'élément en fin de liste.
 E removeFirst(): Supprime et retourne l'élément en début de liste.
 E removeLast(): Supprime et retourne l'élément en fin de liste.
ArrayList vs LinkedList
 Contrairement aux LinkedList, les ArrayList sont
rapides en lecture, même avec un gros volume d'objets.

 Elles sont cependant plus lentes si vous devez ajouter


ou supprimer des données en milieu de liste.

 Pour résumer à l'extrême, si vous effectuez beaucoup


de lectures sans vous soucier de l'ordre des éléments,
optez pour une ArrayList ;

 en revanche, si vous insérez beaucoup de données au


milieu de la liste, optez pour une LinkedList.
AutoBoxing
 Les collections de java.util ne peuvent pas contenir de valeurs
des types primitifs

 l’Autoboxing (depuis la version 1.5) est La possibilité de passer


automatiquement d’un type simple (int, float, double,etc) vers
un type objet correspondant (Integer, Float, Double, etc) et
inversement.

 Exemple: avec AutoBoxing(depuis jdk1.5):


 List<Integer> l = new ArrayList<Integer>();
 l.add(10); int i = l.get(0);

 Exemple: sans AutoBoxing (avant jdk1.5)


 l.add(new Integer(10));
 int i = l.get(0).intValue();
AutoBoxing(2)
 Il existe 2 méthodes remove dans l’interface List : remove(int) et
remove(Object)

 Alors, que fait le code l.remove(7) si l est une List<Integer> ?

 Est-ce que l’autoboxing va s’appliquer ?

 Non, le 7ème élément est enlevé de la liste

 Pour enlever l’élément 7 de la liste d’entiers, il faut caster


explicitement le paramètre :
 l.remove((Integer)7)
Set<E>
 interface Set<E> collection d’objets sans répétition de valeurs

 Correspond à une collection qui ne contient pas 2 objets égaux au


sens de equals (comme les ensembles des mathématiques)

 Les ajouts d'éléments déjà présents sont donc ignorés. Un


élément est déjà présent si un tests equals sur un des éléments
de l'ensemble renvoie vrai.

 Attention! La non duplication d’objets n’est pas assurée dans le


cas où on modifie les objets déjà ajoutés

 Exactement la même interface que Collection, la sémantique des


méthodes est pas la même par add() renvoie false si doublons

 quand on enlève un objet, tout objet égal (au sens de equals) à


l’objet passé en paramètre sera enlevé
Set<E>
 2 classes implantant la sous-interface Set<E>
Set

HashSet SortedSet

NavigableSet

TreeSet

 HashSet<E> implémente Set<E> avec une table de hachage.

 TreeSet<E> implémente NavigableSet<E> extends SortedSet<E>


extends Set<E>
 Les éléments de l’ensemble sont triés selon l’ordre définie par la
méthode int comparTo(Objet o) de l’interface Comparable;
 stocke ses objets dans un arbre binaire de recherche équilibré
HashSet<E>
 Pour que le type E soit décrit dans un HashSet, il doit définir deux
méthodes:

 Boolean equals(Object o): sert à définir l’appartenance d’un élément


à l’ensemble

 Int hashCode(): utilisée pour calculer le code de hachage d’un objet.

 Si c’est deux méthodes sont absentes, le type E utilise celles de la


classe Object

 Les objets placés dans HashSet respectent la règle


 « 2 objets égaux au sens de equals doivent avoir la même valeur
pour la méthode hashCode »

 En effet, cette classe ne vérifie l’égalité que pour les objets qui ont le
même hashCode
HashSet<E>:Exemple1
public Class Point { public Class Teste{
double x,y;
public static void main(String a[]){
public Point(double x, double y){
this.x=x; this.y=y} HashSet<Point> s=new HashSet<Point>()
} s.add(new Point(1,2));
s.add(new Point(2,2));

Point p=new Point(1,2);


s.add(p);
s.add(p);

System.out.println(s)
}}

[1,2]
[1,2] [2,2] [1,2] [1,2] [2,2]
HashSet<E>:Exemple2
public Class Point { public Class Teste{
double x,y;
public Point(double x, double y){ public static void main(String a[]){
this.x=x; this.y=y}
HashSet<Point> s=new HashSet<Point>()

@Override s.add(new Point(1,2));


Public boolean equals(Object o){ s.add(new Point(2,2));
If(! o instanceof Point) return false;
Point p=new Point(1,2);
Point p=(Point) o;
s.add(p);
Return (p.x==x)&& (p.y==y);
s.add(p);
} p.y=5; s.add(p);
}
System.out.println(s)
}}
[1,2]
[1,2] [2,2] [1,2] [1,2] [2,2] [1,2]
[1,2]
[1,2]
[1,5]
[2,2]
[2,2]
HashSet<E>:Exemple 3
public Class Point { public Class Teste{
double x,y;
public Point(double x, double y){ public static void main(String a[]){
this.x=x; this.y=y}
HashSet<Point> s=new HashSet<Point>()

Public boolean equals(Object o){ s.add(new Point(1,2));


If(! o instanceof Point) return false; s.add(new Point(2,2));
Point p=(Point) o;
Return (p.x==x)&& (p.y==y); Point p=new Point(1,2);
} s.add(p);

Public Int hashCode(){ System.out.println(s)


Return x+y;} }}
}

[1,2]
[1,2] [2,2] [1,2] [2,2]
TreeSet<E>(1)
 Avant JDK6.0:
 TreeSet<E> implémente l’interface SortedSet<E> extends Set<E>
 E first() : 1er élément E last() : dernier élément
 subSet(E debut, E fin) : éléments compris entre le début (inclus) et la fin
(exclue)
 headSet(E fin) : éléments inférieurs strictement au paramètre fin
 tailSet(E debut) : éléments qui sont supérieurs ou égaux au paramètre
debut

 Depuis JDK6.0:
 TreeSet<E> implémente NavigableSet<E>extends SortedSet<E>
 Cette interface (JDK 6) permet de naviguer dans un Set à partir d’un de
ses éléments, dans l’ordre du Set ou dans l’ordre inverse
 E lower(E e) , floor(E e) , ceiling(E e) , et higher(E e) retourne
respectivement l’élément inférieur, inférieur ou égal, supérieur, supérieur
ou égal de l’élément e donné en paramètre, null sinon.
TreeSet<E>(2)
Pour que le type E soit décrit dans un TreeSet, il doit implémenter l’interface
Comparable en redéfinissant la méthode int compareTo(Object o) qui
compare l’objet courant à un objet o du type Object.

A.compareTo(B) retourne:
◦ 0 si les deux objets sont égaux A.equals(B) est vrai
◦ un entier négatif si l’objet A est plus petit que B, dans l'ordre de tri souhaité
◦ un entier positif si l’objet A est plus grand que l’objet B.

lorsque l'on ajoute un élément à un ensemble, l'ensemble doit comparer


celui-ci avec les autres éléments déjà présents dans l'ensemble en
utilisant compareTo(Object o)

Dans un TreeSet, la méthode equals n’intervient ni dans


l’organisation de l’ensemble , ni dans le teste d’appartenance. Le
tout est garantie par la méthode compareTo
TreeSet<E>:Exemple:
trier selon l’âge
public Class Person implements Comparable { public Class Teste{
String nom; Int age;
public static void main(String a[]){
public Person(String n, int a){
TreeSet<Person> s=new TreeSet<Person>()
this.nom=n; this.age=a}
s.add(new Person("karim",18));
Public int compareTo(Object o){
s.add(new Person("ali",13));
Person p=(Person) o;
s.add(new Person("Karim",18));
If(this.age <p.age) return -1;
s.add(new Person("said",18));
else if(this.age >p.age) return 1;
System.out.println(s)
else return 0;
}} }
}

[ali,13] [karim,18]
[karim,18] [ali,13] [karim,18]
TreeSet<E>:Exemple:
trier selon l’âge
public Class Person implements Comparable {
String nom; Int age; public Class Teste{

public Person(String n, int a){ public static void main(String a[]){

this.nom=n; this.age=a} TreeSet<Person> s=new TreeSet<Person>()

Public int compareTo(Object o){ s.add(new Person("karim",18));

Person p=(Person) o; s.add(new Person("ali",13));

If(this.age <p.age) return -1; s.add(new Person("Karim",18));

else if(this.age >p.age) return 1; s.add(new Person("said",18));

else if(this.nom.equals(p.nom) )return 0; System.out.println(s)

else return -1
}
}}
}

[ali,13] [karim,18]
[karim,18] [ali,13][said,18] [karim,18]
Parcours d’un ensemble
 Deux méthodes de parcours sont possibles:
 Iterator<E> (ou ListIterator<E>)
 For-each
 le for avec get() ne peut pas être utilisé car la méthode E get(int
index) n’est définie dans l’interface Set<E>

public Class Teste{

public static void main(String a[]){

HashSet<Person> s=new Hashet<Person>()

s.add(new Person("karim",18));
s.add(new Person("ali",13));

Iterator<String> it = L.iterator(); for(Person p : s)


System.out.println(p.nom+p.age);
while(it.hasNext())
System.out.println(it.next() );
Map<K,V>
 Map: « application » (table, tableau associatif)
 Une collection de type Map est une collection qui fonctionne avec un
couple (clé,valeur)association

 1 association = 1 paire « (clé,valeur) » = (k; v)


 Map= ensemble d’associations (k1; v1); (k2; v2) …

 contraintes : 1 seule valeur par clé ! : La clé, qui sert à identifier une
entrée dans notre collection, est unique au sens de equals
 La valeur, au contraire, peut être associée à plusieurs clés.
Clé Valeur
matricule etudiant
 Exemple d’une Map
229910 ali
 MatriculeEtudiant
220987 karim

clé valeur 220983 saïd


Map<K,V>: Implémentation
 Comme pour les ensembles, l’intérêt des tables associatives est de pouvoir y
retrouver rapidement une clé donnée pour en obtenir l’information associée.
Map
 Table de hachage : classe HashMap,

SortedMap
 Arbre binaire : classe TreeMap.

NavigableMap

 Dans les deux cas, seule la clé sera utilisée pour ordonnancer les
informations.

 Dans le premier cas, on se servira du code de hachage des objets formant


les clés

 Dans le second cas, on se servira de la relation d’ordre induite par


compareTo ou par un comparateur fixé à la construction.

 Il existe d’autres implémentations: Hashtable, WeakHashMap


Map<K,V>:interface
Vput(K k, V v) : ajouter v avec la clé k : retourne l’ancienne valeur
associée à la clé si la clé existait déjà
Vget(Object k) : la valeur associée à la clé au sens de equals ou
null
V remove(Object k) : supprimer l’entrée associée à k
boolean containsKey(Object k) : k est-elle une clé utilisée ?
boolean containsValue(Object v) : v est-elle une valeur de la table ?
Set<K> keySet() : l’ensemble des clés
Collection<V> values() : la collection des valeurs
Set<Map.Entry<K, V>> entrySet() : toutes les entrées de la table
putAll(Map<? extends K,? extends V> m) : ajouter les entrées
void

de m
int size() : boolean isEmpty() , void clear() :
HashMap<K,V>
 Structure de données qui permet de retrouver très
rapidement un objet si on connaît sa clé K (accès
en temps constant)

 En interne l’accès aux objets utilise un tableau et


une fonction de hachage appliquée à la clé

 La méthode hashCode() (héritée de Object ou


redéfinie) est utilisée comme fonction de hachage
HashMap<K,V>:Exemple1
idEtudiant : public Class Etudiant {
String nom, prenom;
Map<Integer,Etudiant>
public Etudiant(String x, String y)
Clé Valeur { nom=x; prenom=y}}
id Etudiant
public Class Teste{
2201 [ali,karim]
2202 [said,kamel] public static void main(String a[]){
HashMap<Integer,Etudiant>
HashMap<Integer,Etudiant> m=new
m=new HashMap<Integer,Etudiant>()
HashMap<Integer,Etudiant>()
Clé Valeur
id Etudiant m.put(new Integer(2201), new Etudiant("ali", "karim"));
2201 [ali,karim] m.put(2202, new Etudiant("said", "kamel"));
2202 [rachid,kamel]
Etudiant e=m.get(2202); e.nom="rachid";
Clé Valeur m.remove(2201);
id Etudiant System.out.println(m.containsKey(2001));
2202 [rachid,kamel]
Etudiant f=new Etudiant("rachid", "kamel");
false System.out.println(m.containsValue(f)));
false System.out.println(m.containsValue(e));
true
TreeMap<K,V>
 TreeMap implémente l’interface SortedMap extends Map<k,v>

 Permet de trier les éléments du Map en se basant sur la partie clé K


 on doit pouvoir établir un ordre entre elles  implémenter
l’interface Comparable

 Ajoute à Map des méthodes pour extraire des sous-map, la 1ère ou


la dernière clé (semblable à SortedSet)

 TreeMap Elle implémente aussi l'interface NavigableMap<K,V>


depuis Java 6.

 Ajoute des fonctionnalités à un SortedMap

 Permet de naviguer à partir d’une de ses clés, dans l’ordre du Set ou


dans l’ordre inverse
Parcours d’un Map<k,V>
 Un Map ne propose pas directement d'Iterator sur ses éléments : la
collection peut être parcourue de trois manières :

 parcours de l'ensemble des clés Set<k> keySet()

 parcours des valeurs  Collection<V> values()

 parcours d'un ensemble de paires clé/valeur 


 Set<Map.Entry<K, V>> entrySet()
Parcours d’un Map<k,v>:
par clé
 Map<K, V> m;
 m.keySet()  les clés du Map (Set<K>) ;

 for (K key : m.keySet()) { V value= m.get(key); }

 l'appel de get engendre un temps coûteux en accès à chaque


itération
Map<Integer,Etudiant> m=new HashMap<Integer,Etudiant>()

m.put(2201, new Etudiant("ali", "karim"));


m.put(2202, new Etudiant("said", "kamel"));
for( Integer i:m.KeySet()){
Etudiant e=m.get(i);
System.out.println(e.nom);
Parcours d’un Map<k,v>:
par valeur
 Map<K, V> m;
 m.values()  les valeurs du Map (Collection<V>) ;

 for (V value : m.values() ) { opération sur value}

Map<Integer,Etudiant> m=new HashMap<Integer,Etudiant>()

m.put(2201, new Etudiant("ali", "karim"));


m.put(2202, new Etudiant("said", "kamel"));
for( Etudiant e:m.values()){
System.out.println(e.nom);
Parcours d’un Map<K,V>:
Map.Entry<K,V>
 L’interface Map<K,V> contient l’interface interne public
Map.Entry<K,V> qui correspond à un couple clé-valeur

 Cette interface contient 3 méthodes


 K getKey()
 V getValue()
 V setValue(V valeur)

 La méthode entrySet() de Map renvoie un objet de type


 « ensemble (Set) de Entry »

 On récupère les entrées (paires clé-valeur) sous forme de


Set<Entry<K,V>> avec la méthode entrySet()

 Map<Integer,Etudiant>  Set<Entry<Integer,Etudiant>>
Parcours d’un Map<K,V>:
Map.Entry<K,V>
Map<Integer,Etudiant> m=new HashMap<Integer,Etudiant>()
m.put(2201, new Etudiant("ali", "karim")); m.put(2202, new Etudiant("said", "kamel"));

Set<Entry<Integer,Etudiant>> tous=m.entrySet();

for (Entry<Integer, Etudiant> ligne : tous) {


Integer id = ligne.getKey();
Etudiant e = ligne.getValue();
System.out.println(id+" "+e);
}

Map<Integer,Etudiant> m=new HashMap<Integer,Etudiant>()


m.put(2201, new Etudiant("ali", "karim")); m.put(2202, new Etudiant("said", "kamel"));

for (Entry<Integer, Etudiant> ligne : m.entrySet()) {


Integer id = ligne.getKey();
if(id==2201) ligne.setValue(new Etudiant("said", "farid"));
}

Vous aimerez peut-être aussi