Vous êtes sur la page 1sur 27

Présentation du framework collection

▪ Les tableaux ne peuvent pas répondre à tous les besoins de stockage d'un ensemble
d'objets et surtout ils manquent de fonctionnalités.
▪ La large diversité d'implémentations proposées par l'API Collections de Java permet
de répondre à la plupart des besoins.
▪ Les collections sont des conteneurs qui permettent de regrouper des objets en une
seule entité.
▪ L'API Collections propose de structurer et de définir un ensemble d'interfaces et de
classes de type collection.
▪ Les classes et les interfaces collection sont définies dans le package java.util
L'architecture du framework collection de java
Collection Map

SortedMap
Set List Queue
HashTable HashMap NavigableMap

HashSet SortedSet
LinkedHashMap TreeMap

LinkedHashSet NavigableSet ArrayList Vector LinkedList PriorityQueue

TreeSet
classe
interface
extends
implements
framework Collection
• Le framework Collection propose plusieurs implémentations possédant chacune
un comportement et des fonctionnalités particulières.
Collection Ordonné Accès direct Clé / valeur Doublons Null Thread Safe
ArrayList Oui Oui Non Oui Oui Non
LinkedList Oui Non Non Oui Oui Non
HashSet Non Non Non Non Oui Non
TreeSet Oui Non Non Non Non Non
HashMap Non Oui Oui Non Oui Non
TreeMap Oui Oui Oui Non Non Non
Vector Oui Oui Non Oui Oui Oui
Hashtable Non Oui Oui Non Non Oui
Stack Oui Non Non Oui Oui Oui

« La thread safety d'un code (qu'on appelle alors « code thread-safe ») est la propriété de celui-ci associée au fait qu'il est capable de
fonctionner correctement lorsqu'il est exécuté simultanément au sein du même espace d’adressage par plusieurs threads. »
Interface Collection <E>
▪ Collection : interface qui est implémentée par la plupart des objets qui gèrent
des collections
▪ Principales méthodes :
Méthode Rôle
boolean add(E e) Ajouter un élément à la collection
void clear() Supprimer tous les éléments de la collection
boolean contains(Object o) Retourner un booléen qui précise si l'élément est présent dans la collection
Retourner un booléen qui précise si tous les éléments fournis en
boolean containsAll(Collection<?> c)
paramètres sont présents dans la collection
boolean isEmpty() Retourner un booléen qui précise si la collection est vide
Iterator<E> iterator() Retourner un Iterator qui permet le parcours des éléments de la collection
boolean remove(Object o) Supprimer un élément de la collection s'il est présent
int size() Retourner le nombre d'éléments contenus dans la collection
Object[] toArray() Retourner un tableau contenant tous les éléments de la collection
!! List<T>
▪ L'interface List représente une collection ordonnée de données qui peuvent être des
doublons (données identiques).
▪ Elle peut apparaître comme un tableau qui n'aurait pas la contrainte de taille lorsque vous
récupérez ou y ajoutez des éléments.
▪ En plus des actions globales à l'interface Collection, l’interface List fournit d’autres
méthodes:

Méthode Rôle
void add(int index, T element) Ajouter un élément à la position fournie en paramètre
T get(int index) Retourner l'élément à la position fournie en paramètre
int indexOf(T element) Retourner la première position dans la liste du premier élément fourni en
paramètre. Elle renvoie -1 si l'élément n'est pas trouvé
T remove(int index) Supprimer l'élément à la position fournie en paramètre
T set(int index, T element) Remplacer l'élément à la position fournie en paramètre
Classes implémentant l’interface List<T>
❖ Les classes qui implémentent l'interface List :

• La classe Vector, présente depuis Java 1.0, est un tableau dont la taille peut varier selon le nombre
d'éléments qu'il contient.
• La classe Vector est antérieure à l'API Collections : elle a été mise à jour ultérieurement pour implémenter l'interface List.
Vector • Les éléments sont stockés dans l'ordre dans lequel ils sont ajoutés dans la collection.
• Un élément peut être ajouté ou supprimé à n'importe qu'elle position dans la collection.
• Toutes les méthodes de la classe Vector sont synchronized : elle est donc moins performante que la classe ArrayList car elle
est thread-safe.
• La classe ArrayList, ajoutée à Java 1.2, est un tableau d'objets dont la taille est dynamique
• Le fonctionnement de cette classe est similaire à celui de la classe Vector.
• La classe ArrayList est l'implémentation la plus simple de l'interface List.
ArrayList • Elle présente plusieurs caractéristiques :
o elle n'est pas thread-safe
o elle utilise un tableau pour stocker ses éléments : le premier élément de la collection possède l'index 0
o l'accès à un élément se fait grâce à son index
• La classe LinkedList, ajoutée à Java 1.2, est une implémentation d'une liste doublement chaînée dans laquelle les
LinkedList éléments de la collection sont reliés par des « pointeurs ».
• La suppression ou l'ajout d'un élément se fait simplement en modifiant des « pointeurs ».
7
Exemple d’utilisation d’un ArrayList<T>

8
Egalité entre objets
▪ On utilise la méthode boolean equals(Objet) pour tester l'égalité
▪ Cette méthode est déjà définie dans la classe Object et réalise un test d'égalité par
référence
▪ Pour tester l'égalité par contenu de l'objet, il faut la redéfinir dans les classes
dérivées
▪ Définition de l'égalité par contenu : deux objets égaux par contenu ssi leurs champs
primitifs sont égaux et leurs champs objet égaux par contenu

9
Exemple de méthode equals

Q: Que retourne le code suivant ?


Compte c1=new Compte(1,2000);
Compte c2=new Compte(1,2000);
System.out.println(C1.equals(c2));

10
Tri d’une liste
▪ Il est possible de trier une liste: En utilisant la méthode statique
Collections.sort(List<T> l)

▪ La liste doit contenir des objets dont la classe implémente l’interface Comparable<T>

Q: Comment rendre sa classe Comparable ?

R: En implémentant l'interface avec sa méthode int compareTo(T other)

11
Exemple (1/2)
❑ Trier la liste des comptes dans l’ordre croissant selon le « code »

❖ il est important de maintenir une


cohérence entre la méthode equals()
et la méthode compareTo()
❖ compareTo()==0 est équivalent à
equals()==true

12
Exemple (2/2)
❑ Comment faire si on souhaite utiliser un autre critère de tri : par exemple trier la liste des comptes selon le
« solde » (ordre croissant) ?

13
Exercice
1. Ecrivez la classe Etudiant. Un étudiant est caractérisé par un id, un nom et un prenom. Cette classe possède :
• 2 constructeurs dont un sans paramètre.
• Les méthodes getId(), getNom(), getPrenom(), setId(..), setNom(…), setPrenom(…) permettant d’accéder aux
attributs en écriture et en lecture.
• La redéfinition de la méthode boolean equals(Object o), permettant de tester l'égalité entre 2 étudiants selon l’id.
• La redéfinition de la méthode toString(), permettant de donner une représentation de l'étudiant sous forme d'une
chaîne de caractères
2. Ecrivez un programme main permettant de tester toutes les méthodes de la classe.

3. Créez l’interface IUniversity


public interface IUniversity{
public void ajouterEtudiant(Etudiant e);
public boolean rechercherEtudiant(Etudiant e);
public boolean rechercherEtudiant(String nom);
public void supprimerEtudiant(Etudiant e);
public void displayEtudiants();
public void trierEtudiantsParId();
public void trierEtudiantsParNom();}
4. Construisez la classe UniversityArrayList qui implémente l'interface IUniversity et qui repose sur l'utilisation d’un
ArrayList pour la gestion de la liste des étudiants. 14
Ensembles: Set
▪ Set permet de représenter un ensemble

▪ Les éléments d'un ensemble n'ont pas d'indice contrairement à une liste (pas de méthode T get(int i))

▪ Il ne peut y avoir deux éléments identiques dans un ensemble (au sens de la méthode equals() ou compareTo())

Deux implémentations principales de Set<T> existent :


• HashSet<T> : utilise une table de hachage (nécessite de redéfinir int hashCode())

o L'itération est réalisée selon un ordre arbitraire dépendant des valeurs de hachage

o La classe LinkedHashSet<T> permet d'obtenir un ordre d'itération correspondant à l'ordre d'insertion (une liste
chaînée des éléments est maintenue en parallèle)

• TreeSet<T> : utilise un arbre binaire de recherche pour stocker ses éléments.

o TreeSet<T> implémente SortedSet<T> qui définit les ensembles ordonnés

o L'itération est réalisée selon l'ordre défini sur les objets

o Il est possible d'instancier le TreeSet avec un Comparator personnalisé :


✓ TreeSet<Compte> ts = new TreeSet<>(yxComparator); 15
Ensembles: Set
▪ L'interface Set définit plusieurs méthodes, nous allons citer quelques-unes (méthodes les plus utiles)
Méthodes rôles
boolean add(T e) «interface Collection» Ajouter l'élément fourni en paramètre à la collection si celle-ci ne le contient
pas déjà et renvoyer un booléen qui précise si la collection a été modifiée

boolean remove(T e) «interface Collection» Retirer l'élément fourni en paramètre de la collection si celle-ci le contient
et renvoyer un booléen qui précise si la collection a été modifiée

boolean contains(T e) «interface Collection» Renvoyer un booléen qui précise si la collection contient l'élément fourni en
paramètre
▪ Méthode supplémentaires introduites par l’interface SortedSet<T>
Méthodes rôles
T first() Retourner le premier élément de la collection
T last() Retourner le dernier élément de la collection
SortedSet<T> subSet(T start, T stop) Retourner un sous-ensemble des éléments dont les bornes sont ceux fournis en
paramètres. start est inclus et stop est exclus. Si les deux éléments fournis en
paramètres sont les mêmes, la méthode renvoie une collection vide
SortedSet<T> headSet(T stop) Retourner un sous-ensemble des premiers éléments de la collection jusqu'à
l'élément fourni en paramètre exclus
SortedSet<T> tailSet(T start) Retourner un sous-ensemble contenant les derniers éléments de la collection à
16
partir de celui fourni en paramètre inclus
hashCode() et HashSet
▪ Tout élément ajouté dans un HashSet doit posséder une valeur de hachage
▪ Celle-ci est calculée par la méthode int hashCode() de la classe de l'objet
▪ Une implémentation par défaut de hashCode() existe dans la classe Object : elle se base
exclusivement sur l'adresse mémoire de l'objet sans prendre en compte son contenu
▪ Deux éléments égaux selon equals doivent impérativement retourner le
même hashCode ...mais la réciproque n'est pas toujours vraie : deux éléments de
même hashCode ne sont pas toujours égaux
▪ Il faut toutefois éviter les collisions (la probabilité que deux éléments de même hashCode
soient différents doit être faible) pour ne pas dégrader les performances de HashSet
▪ Un bon réflexe est de toujours redéfinir hashCode lorsque l'on redéfinit la méthode equals
▪ Pour calculer le hashCode, on peut combiner les valeurs des champs primitifs avec
le hashCode des champs objets

17
Exemple d'utilisation de HashSet<T>
Redéfinir la méthode hashCode() dans la classe Compte : On peut maintenant créer un ensemble utilisant une table de
hachage et y ajouter des comptes :

18
Exemple d'utilisation de TreeSet<T>

On note que TreeSet<T> nécessite que le type T des


éléments implémente l'interface Comparable afin de
pouvoir comparer les éléments entre-eux (et avoir un
ordre total).
19
Modification collection pendant itération
On tente d’enlever les comptes dont le solde est égal à zéro

Impossible de modifier la collection via variables de for each

Seul moyen sûr de le faire : via un iterator

20
Itérateur
▪ Un itérateur est un objet de type (interface) Iterator, permettant de « visiter » dans une boucle
tous les éléments d’une collection

▪ Toute collection fournit la méthode Iterator iterator() permettant de fabriquer cet objet

▪ Deux méthodes principales sont donc utilisables pour Iterator<T> :

• boolean hasNext():pour savoir s'il reste des éléments non encore « visités »

• T next():obtenir le « prochain » élément de la collection


▪ Il existe également une méthode void remove() permettant de supprimer l'élément que l'on vient
d'obtenir avec next()pendant l’itération

21
Modifier collection via itérateur
Enlever les comptes dont le solde est égal à zéro

22
Exercice
1. Ecrivez la classe Enseignant
Un enseignant sera caractérisé par un id, un nom et un prenom. Cette classe possède :
• 2 constructeurs dont un sans paramètre.
• Les méthodes getId(), getNom(), getPrenom(), setId(..), setNom(…), setPrenom(…) permettant d’accéder aux attributs
en écriture et en lecture.
• La redéfinition de la méthode méthode boolean equals(Object o), permettant de tester l'égalité entre 2 étudiants selon
l’id.
• La redéfinition de la méthode toString(), permettant de donner une représentation de l’enseignant sous forme d'une
chaîne de caractères

2. Ecrire un programme main permettant de tester toutes les méthodes de la classe.


3. Créez l’interface IGestionEnseignant
public interface IGestionEnseignant{
public void ajouterEnseignant(Enseignant e);
public boolean rechercherEnseignant (Enseignant e);
public boolean rechercherEnseignant (int id);
public void supprimerEnseignant (Enseignant e);
public void displayEnseignants(); }
4. Construisez les classes GestionEnseignantHashSet et GestionEnseignantTreeSet qui implémentent l'interface
IGestionEnseignant et qui reposent sur l'utilisation respective d’un HashSet et d’un TreeSet pour la gestion de la23 liste des
enseignants.
Map
▪ Le type Map<K,V> représente des couples de clé-valeur (K est le type de la clé, V de la valeur)

▪ Tout comme pour Set<T>, il en existe deux implémentations principales :

• HashMap<K,V> qui utilise une table de hachage

• TreeMap<K,V> qui utilise un arbre binaire de recherche pour stocker les clés

▪ On ne peut associer qu'une seule valeur pour une clé donnée, les clés sont toutes uniques

▪ Par contre, les valeurs ne sont pas uniques

24
Map
▪ L’interface Map définit plusieurs méthodes: nous allons citer quelques-unes (méthodes les plus utiles)

Méthodes Rôles
V put(K key, V value) Ajouter un couple dans la Map ; elle retourne l'ancienne valeur
associée à la clé (peut être null si la clé n'était pas déjà présente)
V remove(K key) Supprimer l'élément de la Map dont la clé est fournie en
paramètre
V get(K key) Renvoyer la valeur associée à la clé fournie en paramètre
(retourne null si la clé n'existe pas dans la Map)

Set<K> keySet() Renvoyer un ensemble contenant les clés de la Map

Collection<V> values() Renvoyer une collection qui contient toutes les valeurs des
éléments
Set<Map.Entry<K, V>> entrySet()
Renvoyer un ensemble des couples clé-valeur

25
Exemple d’utilisation de HashMap<K,V>

26
Exercice
1. Ecrivez les classes Employe et Departement
Un employé est caractérisé par un cin, un matricule, un nom et un prenom. Un département est caractérisé par son
identifiant et son nom. Chaque classe possède :
• Deux constructeurs dont un sans paramètre.
• Les getters et les setters
• La méthode toString()
• La méthode equals
2. Créez l’interface ISociete
public interface ISociete {
public void ajouterEmployeDepartement(Employe e,Departement d);
public void supprimerEmploye(Employe e);
public void afficherLesEmployesLeursDepartements();
public void afficherLesEmployes();
public void afficherLesDepartements();
public void afficherDepartement(Employe e);
public boolean rechercherEmploye(Employe e);
public boolean rechercherDepartement(Departement e);
}
3. Construisez les classes SocieteHashMap et SocieteTreeMap qui implémentent l'interface ISociete et qui reposent sur
l'utilisation respective d’un HashMap et d’un TreeMap pour la gestion des employés ainsi que leurs départements respectifs.
27

Vous aimerez peut-être aussi