Académique Documents
Professionnel Documents
Culture Documents
8 novembre 2023
1
Iterable<E>
Collection<E> Map
SortedSet<E>
Collection
et t t e t
t hS et Lis is qu is
Se a s
e S y d L De dL
sh ed
H
re rra ke ay ke
Ha n k T A Lin
Ar r
L in
Li
2
Map
ap
p p hM
Ma Ma s
a SortedMap
sh ee dH
Ha Tr nk
e
Li
1 Collection<E> maCollection;
2 ...
3 for (E <nom> : maCollection)
4 // block d'instructions
Dans le code ci-dessus, nous avons une une collection maCollection qui
contient des objets de type E. On va accéder à chaque élément de la collection
maCollection en utilisant une boucle “for each”. Chaque élément sera
stocké dans une variable <nom> de type E (évidemment).
Un autre exemple où le type E est remplacé par le type Velo est donné
ci-dessous.
1 List<Velo> velos =
2 new ArrayList<Velo>();
3
4 velos.add(new Velo("Poulidor"));
5 velos.add(new Velo("Merckx"));
6 velos.add(new Velo("Hinault"));
7 velos.add(new Velo("Jalabert"));
8 velos.add(new Velo("Alaphilippe"));
9
10 for (Velo v: velos)
11 System.out.println(v);
3
L’interface Iterator. Un objet qui implémente l’interface Iterator est dé-
dié au parcourt d’éléments dans une collection. On obtient un tel objet en uti-
lisant la méthode iterator() d’un objet implémentant l’interface Iterable.
1 List<Velo> velos
2 = new ArrayList<Velo>();
3 velos.add(new Velo("Poulidor"));
4 velos.add(new Velo("Merckx"));
5 velos.add(new Velo("Hinault"));
6 velos.add(new Velo("Jalabert"));
7 velos.add(new Velo("Alaphilippe"));
8
9 Iterator<Velo> it = velos.iterator();
10 while (it.hasNext()){
11 Velo v = it.next();
12 if (v.getName().equals("Merckx"))
13 it.remove();
14 else
15 System.out.println(v);
16 }
Parcours d’un Map. Un Map n’est pas une collection. C’est donc un ob-
jet plus difficile à parcourir. , En effet, Map n’est pas une sous interface de
Iterable, donc on ne peut pas parcourir un Map avec une boucle for
4
each ni avec un Iterator ! Pour présenter un peu ce type d’objet, voici
quelques descriptions des méthodes qu’il peut utiliser.
Interface Map<K,V>
V get(Object key)
Returns the value to which the specified key is map-
ped, or null if this map contains no mapping for the
key.
V put(K key, V value)
Associates the specified value with the specified key
in this map. If the map previously contained a map-
ping for the key, the old value is replaced by the spe-
cified value.
V remove(Object key)
Removes the mapping for a given key if it is present.
default V replace(K key, V value)
Replaces the entry for the specified key only if it is
currently mapped to some value. Returns the value
to which this map previously associated the key, or
null if the map contained no mapping for the key.
Pour parcourir un Map, on peut se ramener à une Collection en utilisant
certaines méthodes. En effet, on peut obtenir l’ensemble des clés, l’ensemble
des valeurs, et l’ensemble des paires (clé,valeur) grace aux méthodes suivantes :
— Set<K> keySet() donne l’ensemble des clés ;
— Collection<V> values() donne la collection des valeurs ;
— Set<Map.Entry<K,V» entrySet() donne l’ensemble des paires
clé-valeur.
Interface Map.Entry<K,V>
K getKey()
Returns the key corresponding to this entry.
V getValue()
Returns the value corresponding to this entry.
V setValue(V value)
Replaces the value corresponding to this entry with the
specified value (optional operation).
5
Grâce à l’interface Map.Entry nous pouvons parcourir un Map comme
illustré ci-dessous. Dans cet exemple, on utilise la méthode entrySet pour
se ramener à une collection et utiliser une boucle for each.
Dans cet exemple, on part d’une Map qui associe à chaque velo sa marque et
on affiche seulement les velos qui sont de marque Giant.
6
add remove contains
? ?
HashSet temps constant temps constant temps constant?
TreeSet log(n) log(n) log(n)
La classe TreeSet stock les éléments d’un ensemble (ordonné) dans une
structure de donnée appelée arbre rouge-noir. Un arbre rouge noir permet
des compléxités logarithmiques en n pour les opérations usuelles du Set où
n est le nombre d’éléments dans l’ensemble. La classe HashSet utilise une
table de hachage. En pratique les opérations sont très rapides. Ajouter un élé-
ment ou enlever un élément se fait en temps constant (une fois l’opération
de recherche effectuée). Cependant, la compléxité pire cas de l’opération de
recherche va dépendre du facteur de charge comme nous allons l’expliquer
maintenant.
Une solution pour résoudre ces collisions consiste à utiliser une liste dou-
blement chainée : on stocke tous les éléments qui ont une même valeur de
hachage dans une liste chaînée. Chaque case de la table de hachage contient
alors une référence vers la tête de la liste. En fait à partir de Java 8, quand
une case de la table de hachage contient trop d’éléments, cette liste chainée
est remplacée par une arbre binaire de recherche.
Supposons qu’on ait k valeurs de hachage et n éléments. Dans le pire cas,
les n éléments ont la même valeur de hachage, on aura alors simplement une
longue liste chainée. D’un point de vue algorithmique la table de hachage
perd alors tout intérêt ! Dans la situation idéale, les n éléments sont répartis
uniformément sur les k valeurs de hachage. Si on récapitule.
— l’insertion d’un élément se fait donc en O(1) (il faut d’abord vérifier que
l’élément n’est pas contenu si on a un Set.)
— enlever un élément se fait en O(1) si la liste est doublement chaînée.
— cherche un élément se fait en Θ(1+α) où α est le nombre moyen d’élé-
ments stockés dans une chaîne. α est aussi appelé facteur de charge.
7
Pour que notre table de hachage soit la plus performante possible, on vou-
drait une fonction qui distribue de manière uniforme toutes les clés dans cha-
cun des k valeurs possibles de hachage. Cependant, cette tâche est difficile
car on ne connait que rarement la probabilité qu’on ait un élément avec une
certaine clé. Il existe des techniques pour générer de bonnes fonctions de ha-
chage, mais ce n’est pas l’objet de ce cours.
La boucle for each est la plus simple à utiliser pour écrire rapidement
une boucle. Lors de la compilation, Java va traduire cette ligne en utilisant
un Iterator. , Attention à l’intérieur de la boucle, on ne peut pas modifier
la collection (par exemple avec remove()). Si vous modifiez la collection en
cours de parcours, cela causera une ConcurrentModificationException.
La bonne façon de procéder consiste alors à utiliser un Iterator.
8
Ordre
L’interface Comparable. L’interface Comparable contient une seule mé-
thode :
Cette méthode retourne 1) un entier négatif si l’objet est plus petit que
l’objet passé en paramètre ; 2) zéro s’ils sont égaux ; 3) un entier positif si l’ob-
jet est plus grand que l’objet passé en paramètre. Les classes String, Integer,
Double, Date, GregorianCalendar et beaucoup d’autres implémentent
toutes l’interface Comparable.
Par exemple, en TD vous avez creez une classe Box qui implémente l’in-
terface Comparable.
Par exemple, Pour comparer des Box, selon ordHG, on peut écrire la classe
suivante :
9
5 }
6 }
Trier les éléments d’une collection. Pour trier une collection, différentes
méthodes sont possibles. Premièrement, nous pouvons utiliser la méthode
sort de l’interface List (si nous avons une List). Cette méthode prend en
paramètre un objet Comparator.
Description : Sorts this list according to the order induced by the specified
Comparator. All elements in this list must be mutually comparable using
the specified comparator. If the specified comparator is null then all ele-
ments in this list must implement the Comparable interface and the ele-
ments’ natural ordering should be used.
1 // classe Collections
2 public static <T extends Comparable<? super T>>
3 void sort(List<T> list)
4 public static <T> void sort
5 (List<T> list, Comparator<? super T> c)
10
1 public static void main(String[] args){
2 List<Velo> velos = new ArrayList<>();
3 ...
4
5 for (Velo v: velos)
6 System.out.println(v.presentation());
7 velos.sort(null);
8 //ou Collections.sort(velos);
9 for (Velo v: velos)
10 System.out.println(v.presentation());
11
12 Comparator<Velo> ordre = new OrdrePuissance();
13 velos.sort(ordre);
14 //ou Collections.sort(velos,ordre);
15 for (Velo v: velos)
16 System.out.println(v.presentation());
17 }
11