les conteneurs java ou collections - …daniel.tschirhart.free.fr/java/cours/conteneursjava.pdf ·...
TRANSCRIPT
Les conteneurs Java Les conteneurs Java ou Collections ou Collections
Daniel Tschirhart : Programmation Java V1.34
Daniel Tschirhart : Programmation Java V1.34
2
Type de DonnType de Donnéée Abstrait (T.D.A.)e Abstrait (T.D.A.)
� Un conteneur est un Type de Donnée Abstrait (T.D.A.) (également appelécollection) destiné à contenir des objets. Il existe deux types de conteneurs :� Les conteneurs séquentiels :
� Les vecteurs, piles, files, sacs, ensembles
� Les conteneurs associatifs : � Les dictionnaires (map)
Daniel Tschirhart : Programmation Java V1.34
3
Conteneurs sConteneurs sééquentielsquentiels
� les vecteurs (tableau), � Les piles� Les files� Les sacs� Les ensembles
Daniel Tschirhart : Programmation Java V1.34
4
Les vecteursLes vecteurs� Dans un vecteur la donnée est
directement accessible à l’aide d’un index appelé indice.
� Une implémentation directe d’un vecteur peut être réalisée à l’aide d’un vecteur classique, mais d’autre structures de données sont possibles.
� Un vecteur se prête mal pour l’ajout ou la suppression gestion des données.
indice maximal
indice minimal
Tableau T
Daniel Tschirhart : Programmation Java V1.34
5
Les PilesLes Piles
� Deux opérations principales sont permises : empiler (insérer à la tête ou un sommet) et dépiler (supprimer au sommet).
v3
v1
v2
v3 v3
v1
v2
v3
v3
v1
v2
v3
avant empilement après empilementet avant dépilement
après dépilement
Sommet de pile (TOS)
Daniel Tschirhart : Programmation Java V1.34
6
Les Files Les Files fifofifo
� Une file est comme la pile, une structure de données à accès restreint. Deux opérations principales sont permises : ajouter (insérer à la queue de la file) et suivant (obtenir l’élément en tête le retirer de la file).
v4v2v6
v2
v4v2v6v2
v4
v2v6v2
avant l'ajout de v2dans la file
après l'ajout de v2et avant la sortie dela tête de file
après la sortie dela tête de file
Queue Tête
Daniel Tschirhart : Programmation Java V1.34
7
Les Sacs (Les Sacs (bagsbags))
� Un TDA de type sac est une collection de données non ordonnée. Un sac peut contenir plusieurs fois la même donnée. Un sac est utilisé pour stocker des objets, l’ordre dans le quel les objets sont stockés n’ayant aucune importance.
Ajout de V4 et V2 dans un sac
Daniel Tschirhart : Programmation Java V1.34
8
Les ensembles (set)Les ensembles (set)
� Les ensembles sont similaires aux sac, excepté qu’il ne peuvent contenir plusieurs données identiques.
� Ce type de collection implémente les opération sur les ensembles (union, intersection, ...).
Daniel Tschirhart : Programmation Java V1.34
9
Structures de donnStructures de donnéées es fondamentalesfondamentales
� Les structures de donnée fondamentales (S.D.F.) sont la représentation concrète des types de données abstrait
Daniel Tschirhart : Programmation Java V1.34
10
Structures de donnStructures de donnéées utilises utiliséées es utilisutilisééeses dans les T.D.A.dans les T.D.A.
� Tableau� Un tableau peut être utiliser pour
implémenter directement un vecteur, une pile, une file, un sac. L’accès est très rapide mais l’ajout ou la suppression des données en dehors du haut du tableau est proportionnelle à la taille du tableau.
Daniel Tschirhart : Programmation Java V1.34
11
Structures de donnStructures de donnéées es utilisutilisééeses
� Tableau� Un tableau peut être utiliser pour
implémenter directement un vecteur, une pile, une file, un sac. L’accès est très rapide mais l’ajout ou la suppression des données en dehors du haut du tableau est proportionnelle à la taille du tableau.
Daniel Tschirhart : Programmation Java V1.34
12
Liste liListe liééee
L I S T E
� Une liste liée est un ensemble d'éléments organisés séquentiellement et reliés par des lien explicites
Daniel Tschirhart : Programmation Java V1.34
13
Liste liListe liéée (2)e (2)
� La figure met en évidence les éléments suivants :� Chaque nœud possède un lien, ce qui implique que le dernier nœud
doit référer un nœud suivant. On convient alors d'un nœud sentinelle ou nœud factice (figure ci-dessous).
� Chaque nœud est repéré par un lien précédent ce qui implique que le premier nœud doit posséder un élément qui le repère. Ce nœud sera appelé entête (figure ci-dessous). De même que la fin de la liste doit spécifier un repère de fin (sentinelle).
Daniel Tschirhart : Programmation Java V1.34
14
RRééorganisation d'une liste organisation d'une liste
L I S T E
LI S TE
Entête
Entête
Sentinelle
Sentinelle
Daniel Tschirhart : Programmation Java V1.34
15
Insertion et suppression d'un Insertion et suppression d'un éélléément dans une liste liment dans une liste liéée e
LEntête I T ES
X
Sentinelle
LEntête I T ES
X
Sentinelle
Daniel Tschirhart : Programmation Java V1.34
16
Listes doublement liListes doublement liéées es
Ce type de liste permet d’atteindre avec la même efficacité, la tête de liste et la fin de liste.
Daniel Tschirhart : Programmation Java V1.34
17
Les arbres binairesLes arbres binaires� Un arbre est une liste liée où chaque nœud pointe en avant sur plusieurs
nœuds. � La racine de l'arbre est le premier nœud.
� Un sous-arbre est constitué d'un nœud est de tous les nœuds en dessous de lui. � Le nœud terminal (feuille) est un nœud sans descendant. � Un nœud donné a un parent (le nœud au-dessus de lui) sauf si c'est la racine, peut
avoir des frères (les nœuds issus d'un même parent) ou des descendants (nœuds qu'il pointe directement).
� Les arbres binaires sont utilisés par le conteneur TreeMap
Daniel Tschirhart : Programmation Java V1.34
18
Exemple d'arbre binaireExemple d'arbre binaire
Daniel Tschirhart : Programmation Java V1.34
19
Tables Tables àà adressage dispersadressage disperséé((hastablehastable))
� Les tables à adressage dispersé (table de hachages) sont utilisés dans java pour accélérer (considérablement) le recherche d’un élément dans un conteneur non trié. � Exemple : sans hachage la recherche d’un
élément dans un conteneur séquentiel nécessite en moyenne de parcourir taille/2 éléments (taille = nombre d’éléments dans le conteneur).
Daniel Tschirhart : Programmation Java V1.34
20
Constitution d'une table de hachageConstitution d'une table de hachage
� La table de hachage est constituée d’un tableau de listes chaînées
� Chaque emplacement de tableau est appelé seau
Daniel Tschirhart : Programmation Java V1.34
21
Fonctionnement d'une table de hachageFonctionnement d'une table de hachage
� Pour trouver la place d’un élément dans le tableau (numéro du seau) on calcule son code de hachage puis on le réduit par le modulo du nombre total de seaux. Exemple :� code de hachage calculé= 345 avec 100 seaux, l’objet
est placé dans le seau 45 (345:100=45)� avec un peu de chance le seau sera vide, sinon
(collision de hachage) il faut parcourir la liste comportant tous les éléments du seau pour déterminer si l’objet en fait partie.
� En utilisant des codes de hachage distribués aléatoirement et avec un nombre de seaux suffisamment grand (+50% de la taille de collection) il suffit en général d’effectuer uniquement quelques comparaisons
Daniel Tschirhart : Programmation Java V1.34
22
Le choix d'un conteneurLe choix d'un conteneur
� Le choix d'un conteneur doit être adapté au problème à traiter :� L'accès à un objets doit t'il être direct ou peut-il
être séquentiel ?� Le conteneur doit-il être triés ?� L'ordre d'insertion ou d'extraction a-t-il une
importance ?� Doit–on insérer ou supprimer un objet au milieu
d'une collection ?� Un objet peut t-il être dupliqué à l'intérieur d'une
collection ?
Daniel Tschirhart : Programmation Java V1.34
23
Les collections sLes collections sééquentielles quentielles dans Javadans Java
Collection
List
ArrayList Vector LinkedList
Set
SortedList HashSet
TreeSetStack
Daniel Tschirhart : Programmation Java V1.34
24
Parcourir les collections Parcourir les collections
� Tous les conteneurs sauf Stack, sont parcourus de la même manière à l'aide d'un itérateur.
� Un iterateur est un objet permettant de faire l'abstraction de la structure de donnée fondamentale sous jacente du conteneur. Ainsi les conteneurs Vector, ArrayList, LinkedListincorporent tous un objet de type Iterator.
� Principales méthodes d'un itérateur Java
Daniel Tschirhart : Programmation Java V1.34
25
Exemple de parcours d'une Exemple de parcours d'une liste liste àà ll’’aide daide d’’un itun itéérateurrateur
List<Complex> l = new LinkedList<Complex>();
l.add(new Complex(3,5));
Iterator<Complex> it = l.iterator();
while (it.hasNext())
System.out.println(it.next());
Daniel Tschirhart : Programmation Java V1.34
26
Boucle Boucle foreachforeach
� Java 5 possède une nouvelle construction for (foreach) simplifiant le parcours d’une collection. Ici l1 est un objet de type String
for (String s : l1)
System.out.println(s);
Daniel Tschirhart : Programmation Java V1.34
27
Suppression dSuppression d’’un un éélléément dans ment dans une collectionune collection
� Pour supprimer un élément du conteneur il faut l'avoir lu auparavant :
it.next();
it.remove();
it.remove(); // faux
it.next(); // correct
it.remove();
it.next();
it.remove();
Daniel Tschirhart : Programmation Java V1.34
28
Interface ListInterface List
� Cette interface déclare les méthodes que doit implémenter ArrayList, Vector, LinkedList
Daniel Tschirhart : Programmation Java V1.34
29
VectorVector, , ArrayListArrayList, , LinkedListLinkedList
� Ces conteneurs sont des tableaux dynamiques (leur taille augmente automatiquement).
� Ils sont bien adaptés pour manipuler les données situés à un indice quelconque sauf au début ou à la fin de la liste auquel cas il faut leur préférer la liste liée LinkedList.
� Toutes ces classes dérivent de l'interface List.
Daniel Tschirhart : Programmation Java V1.34
30
Classe Classe VectorVector
� Tableau qui s'agrandi automatiquement.� La classe est dite synchronisée : l'accès
d'un objet de type Vector peut être effectué de façon concurrente.
� Exemple d'utilisation :
List<Complex> l = new Vector<Complex>();
l.add(new Complex(3, 4));
Daniel Tschirhart : Programmation Java V1.34
31
Classe Classe ArrayListArrayList
� Liste implémentés à l'aide d'un tableau. � La classe n'est pas synchronisée.� Exemple d'utilisation :
List<Complex> l = new ArrayList<Complex>();
l.add(new Complex(3, 4));
Daniel Tschirhart : Programmation Java V1.34
32
Classe Classe LinkedListLinkedList
� Liste implémentés à l'aide d'une liste liée. � La classe n'est pas synchronisée.� Exemple d'utilisation :
List<Complex> l = new LinkedList<Complex>();
l.add(new Complex(3, 4));
Daniel Tschirhart : Programmation Java V1.34
33
import java.util.*;public class TestListe1{
public static void main(String[] args){
List<String> l1 = new ArrayList<String>();l1.add("-L3-"); l1.add("-L2-"); l1.add("-L1-"); l1. add("-L0-");// Afficher la listeSystem. out.println(l1);// Parcourir la listefor (Iterator<String> it = l1.iterator(); it.hasNex t(); )
System. out.println(it.next());// Trier la listeCollections. sort(l1);System. out.println(l1);// Parcourir la liste avec foreachfor (String s : l1)
System. out.println(s);//Supprimer le deuxième élément;Iterator<String> it = l1.iterator();it.next();it.next();it.remove();System. out.println(l1);
}}
Exemple completExemple complet
Daniel Tschirhart : Programmation Java V1.34
34
Liste : exemple 2Liste : exemple 2
Exemple List
Daniel Tschirhart : Programmation Java V1.34
35
Liste : exemple 3Liste : exemple 3
� On veut insérer, dans l’exemple ci-dessus, si un élément en tête de liste. On ne peut pas le faire à l’aide de la méthode générale add de l'interface list, mais avec la méthode addFirst de la classe LinkedList� Justification : addFirst n’est pas présente dans l’interface List
parce que cette opération est très coûteuse pour les structures de données de type vecteur.
� Pour utiliser addFirst il faut créer directement un objet du type LinkedList. En affichant la liste on obtient
Exemple List2
Daniel Tschirhart : Programmation Java V1.34
36
Classe Classe VectorVector : exemple 4: exemple 4
Exemple Vector
Daniel Tschirhart : Programmation Java V1.34
37
Classe Classe StackStack
� Une pile est un conteneur séquentiel. Les piles java utilisent une SDF vecteur
Daniel Tschirhart : Programmation Java V1.34
38
Ensembles Ensembles HashSetHashSet, , TreeSetTreeSet
� HashSet et TreeSet implémentent l’interface Set
� HashSet utilise une table d’adressage dispersée, alors que TreeSet utilise un arbre binaire.
� L’accès aux éléments d’un ensemble ne se fait pas à l’aide d’un indice et une seule occurrence de donnée est autorisée dans l’ensemble.
Daniel Tschirhart : Programmation Java V1.34
39
MMééthodes disponibles dans thodes disponibles dans ll’’interface interface SetSet
Daniel Tschirhart : Programmation Java V1.34
40
Exemples utilisant lExemples utilisant l’’interface interface SetSet
Daniel Tschirhart : Programmation Java V1.34
41
Conteneurs associatifs Conteneurs associatifs
� Les données sont organisées par paires : clé + donnée.
Map<String, String> m = new TreeMap<String, String>();
m.put("Lajoie", "05 46 66 33 50");
� "Lajoie" est la clé, "05 46 66 33 50" la donnée.
� La clé ou index sert à retrouver la donnée associée.
Daniel Tschirhart : Programmation Java V1.34
42
HiHiéérarchie des classes des rarchie des classes des conteneurs associatifsconteneurs associatifs
Daniel Tschirhart : Programmation Java V1.34
43
Classe MAP (Interface)Classe MAP (Interface)
Daniel Tschirhart : Programmation Java V1.34
44
Classe Classe TreeMapTreeMap
� Un dictionnaire TreeMap trie les clés.Exemple : annuaire téléphonique utilisant un TreeMap
Daniel Tschirhart : Programmation Java V1.34
45
Manipulation dManipulation d’’un un TreeMapTreeMap
Un TreeMap ne permet pas de récupérer les clés individuellement (index). Il faut utiliser un ensemble Set
On récupère une clé -> s
puis on récupère la donnée associée à la clé que l'on l'utilise pour indexer le dictionnaire
Daniel Tschirhart : Programmation Java V1.34
46
Classe Classe HashMapHashMap
� Ne trie pas les clés mais offre un accès 20% plus rapide que le conteneur précédent.
� On peut reprendre intégralement les exemples précédents en remplaçant TreeMap par HashMap