Les conteneurs Java ou Collections

Transcription

Les conteneurs Java ou Collections
Les conteneurs Java
ou Collections
Daniel Tschirhart : Programmation Java V1.34
Daniel Tschirhart : Programmation Java V1.34
Type de Donné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)
2
Daniel Tschirhart : Programmation Java V1.34
Conteneurs séquentiels
les vecteurs (tableau),
Les piles
Les files
Les sacs
Les ensembles
3
Daniel Tschirhart : Programmation Java V1.34
Les 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.
Tableau T
indice maximal
indice minimal
4
Daniel Tschirhart : Programmation Java V1.34
Les Piles
Deux opérations principales sont permises :
empiler (insérer à la tête ou un sommet) et
dépiler (supprimer au sommet).
Sommet de pile (TOS)
v3
v3
v2
v2
v2
v1
v1
v1
v3
v3
v3
avant empilement
après empilement
et avant dépilement
v3
après dépilement
5
Daniel Tschirhart : Programmation Java V1.34
Les Files fifo
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).
Queue
v2
Tête
v6 v2 v4
v2 v6 v2 v4
v2 v6 v2
avant l'ajout de v2
dans la file
après l'ajout de v2
et avant la sortie de
la tête de file
après la sortie de
la tête de file
v4
6
Daniel Tschirhart : Programmation Java V1.34
Les Sacs (bags)
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
7
Daniel Tschirhart : Programmation Java V1.34
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, ...).
8
Daniel Tschirhart : Programmation Java V1.34
Structures de données
fondamentales
Les structures de donnée
fondamentales (S.D.F.) sont la
représentation concrète des types de
données abstrait
9
Daniel Tschirhart : Programmation Java V1.34
Structures de données utilisées
utilisées 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.
10
Daniel Tschirhart : Programmation Java V1.34
Structures de données
utilisées
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.
11
Daniel Tschirhart : Programmation Java V1.34
Liste liée
L
Une liste liée est un ensemble d'éléments
organisés séquentiellement et reliés par des
lien explicites
I
S
T
E
12
Daniel Tschirhart : Programmation Java V1.34
Liste lié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).
13
Daniel Tschirhart : Programmation Java V1.34
Réorganisation d'une liste
Entête
L
I
S
T
E
Sentinelle
Entête
E
I
S
T
L
Sentinelle
14
Daniel Tschirhart : Programmation Java V1.34
Insertion et suppression d'un
élément dans une liste liée
X
Entête
L
I
S
T
E
Sentinelle
X
Entête
L
I
S
T
E
Sentinelle
15
Daniel Tschirhart : Programmation Java V1.34
Listes doublement liées
Ce type de liste permet d’atteindre avec la même efficacité, la tête de liste et la fin de
liste.
16
Daniel Tschirhart : Programmation Java V1.34
Les 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
17
Daniel Tschirhart : Programmation Java V1.34
Exemple d'arbre binaire
18
Daniel Tschirhart : Programmation Java V1.34
Tables à adressage dispersé
(hastable)
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).
19
Daniel Tschirhart : Programmation Java V1.34
Constitution 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
20
Daniel Tschirhart : Programmation Java V1.34
Fonctionnement 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
21
Daniel Tschirhart : Programmation Java V1.34
Le 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 ?
22
Daniel Tschirhart : Programmation Java V1.34
Les collections séquentielles
dans Java
Collection
List
ArrayList
Vector
Stack
Set
LinkedList
SortedList
HashSet
TreeSet
23
Daniel Tschirhart : Programmation Java V1.34
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, LinkedList
incorporent tous un objet de type Iterator.
Principales méthodes d'un itérateur Java
24
Daniel Tschirhart : Programmation Java V1.34
Exemple de parcours d'une
liste à l’aide d’un itérateur
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());
25
Daniel Tschirhart : Programmation Java V1.34
Boucle foreach
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);
26
Daniel Tschirhart : Programmation Java V1.34
Suppression d’un élément dans
une collection
Pour supprimer un élément du conteneur il faut l'avoir lu
auparavant :
it.next();
it.remove();
it.remove();
it.next();
it.remove();
it.next();
it.remove();
// faux
// correct
27
Daniel Tschirhart : Programmation Java V1.34
Interface List
Cette interface déclare les méthodes que doit
implémenter ArrayList, Vector, LinkedList
28
Daniel Tschirhart : Programmation Java V1.34
Vector, ArrayList, LinkedList
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.
29
Daniel Tschirhart : Programmation Java V1.34
Classe Vector
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));
30
Daniel Tschirhart : Programmation Java V1.34
Classe ArrayList
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));
31
Daniel Tschirhart : Programmation Java V1.34
Classe LinkedList
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));
32
Daniel Tschirhart : Programmation Java V1.34
Exemple complet
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 liste
System.out.println(l1);
// Parcourir la liste
for (Iterator<String> it = l1.iterator(); it.hasNext(); )
System.out.println(it.next());
// Trier la liste
Collections.sort(l1);
System.out.println(l1);
// Parcourir la liste avec foreach
for (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);
}
}
33
Daniel Tschirhart : Programmation Java V1.34
Exemple List
Liste : exemple 2
34
Daniel Tschirhart : Programmation Java V1.34
Exemple List2
Liste : 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
35
Daniel Tschirhart : Programmation Java V1.34
Exemple Vector
Classe Vector : exemple 4
36
Daniel Tschirhart : Programmation Java V1.34
Classe Stack
Une pile est un conteneur
séquentiel. Les piles java
utilisent une SDF vecteur
37
Daniel Tschirhart : Programmation Java V1.34
Ensembles HashSet, TreeSet
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.
38
Daniel Tschirhart : Programmation Java V1.34
Méthodes disponibles dans
l’interface Set
39
Daniel Tschirhart : Programmation Java V1.34
Exemples utilisant l’interface
Set
40
Daniel Tschirhart : Programmation Java V1.34
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.
41
Daniel Tschirhart : Programmation Java V1.34
Hiérarchie des classes des
conteneurs associatifs
42
Daniel Tschirhart : Programmation Java V1.34
Classe MAP (Interface)
43
Daniel Tschirhart : Programmation Java V1.34
Classe TreeMap
Un dictionnaire TreeMap trie les clés.
Exemple : annuaire téléphonique utilisant un
TreeMap
44
Daniel Tschirhart : Programmation Java V1.34
Manipulation d’un TreeMap
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
45
Daniel Tschirhart : Programmation Java V1.34
Classe HashMap
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
46