• Aucun résultat trouvé

[PDF] Document Java cours et exercices pour debuter la programmation objet | Cours java

N/A
N/A
Protected

Academic year: 2021

Partager "[PDF] Document Java cours et exercices pour debuter la programmation objet | Cours java"

Copied!
10
0
0

Texte intégral

(1)

Introduction aux collections Java

Ensimag 2A 2014-15 - TP POO

Résumé

Ce document présente le concept des collections Java, les principales classes et leur utilisation. Avec les exemples donnés, ceci est normalement suffisant pour la réalisation du TP ; vous n’utiliserez d’ailleurs pas tout ce qui est présenté.

Il s’agit ici de pédagogie inversée : après avoir d’abord découvert de vous-même ces notions par la pratique, les collections seront ensuite abordées à nouveau plus en profondeur dans la fin du cours.

1

Principe

Les collections Java sont un ensemble de classes définissant des structures de données efficaces pour stocker, rechercher et manipuler des objets. De nombreuses structures existent couvrant les besoins les plus courants : séquences d’éléments, ensembles quelconques, ensembles ordonnés, queues (files, piles, files à priorité) ou encore des dictionnaires associatifs entre des clés et des valeurs. Ces « types de données abstraits » sont spécifiés dans desinterfaceJava de haut niveau, puis implantés dans différentes classes concrètes. Les collections sont génériques : elles permettent de stocker des objets de tout type (Object, String,MaClasse, ...). Il est aussi possible de gérer des types de base via des classes « wrapper » (Integer pourint,Doublepourdouble, ...). Le choix d’une collection dépend de l’utilisation recherchée et des coûts des opérations principalement réalisées.

Il existe en fait deux hiérarchies de classes :

— celle des collections proprement dites, qui sont filles de l’interfaceCollection<E>(figure1). Elles permettent de stocker des éléments.

— celle des dictionnaires associatifs contenant des couples<clé,valeur>, dont la racine est l’interface Map<K,V> (figure2).

Important : avant de se lancer dans le développement éventuel de vos propres structures de données, il est toujours préférable de d’abord chercher parmi les collections celles qui répondent le mieux à vos besoins. Dans la majorité des cas les structures adéquates existent déjà, qui plus est implantées de manière efficace et validées.

Ce document présente les principes d’utilisation des principales collections. De nombreuses ressources sont également disponibles, notamment :

— l’APIhttp://docs.oracle.com/javase/7/docs/api(indispensable !). Toutes les classes et inter-faces discutées ici sont dans le paquetagejava.util ;

— les Java Tutorials :http://docs.oracle.com/javase/tutorial/collections/index.html

2

Parcours d’une collection : itérateur et for each

Le mécanisme d’itération permet de parcourir séquentiellement tous les éléments d’une collection, de manière uniforme et efficace.

Toute collection possède une méthodeIterator<E> iterator() qui retourne un itérateur permettant d’accéder aux éléments un par un en « avançant » dans la collection. Initialement, l’itérateur est placé « avant » le premier élément. A chaque accès, le prochain élément est retourné et l’itérateur avance à l’élément suivant. Lors du parcours complet d’une collection, chaque élément est retourné une et une seule fois, dans un ordre dépendant du type exact de la collection.

Les deux méthodes principales d’un itérateur sont :

— public boolean hasNext()qui retournetrues’il reste des éléments dans l’itération ;

— public E next()qui retourne le prochain élément et avance dans l’itération. S’il n’y a plus d’élément,

uneNoSuchElementException est levée.

(2)

« interface » Collection<E> « interface » List<E> « interface » Queue<E> « interface » Deque<E> « interface » Set<E> « interface » SortedSet<E>

ArrayList<E> LinkedList<E>LinkedList<E> PriorityQueue<E>

TreeSet<E>

HashSet<E>

Figure 1 – Hiérarchie des principales collections Java : des interfaces (spécifications purement abstraites) et les classes concrètes utilisables en pratique :ArrayList<E>,LinkedList<E>,PriorityQueue<E>,HashSet<E> et TreeSet<E>. « interface » Map<KV> « interface » Map<K,V> « interface » SortedMap<KV> « interface » SortedMap<K,V> HashMap<KV>

HashMap<K,V> TreeMap<K,V>TreeMap<KV>

Figure 2 – Hiérarchie des principaux dictionnaires associatifs, définissant essentiellement deux classes concrètes :HashMap<K,V>etTreeMap<K,V>.

(3)

1 C o l l e c t i o n < E > c o l l = ... ; // C o l l e c t i o n e x i s t a n t e , de t y p e q u e l c o n q u e 2 3 I t e r a t o r < E > it = c o l l . i t e r a t o r () ; // Cr é e un n o u v e l it é rateur , 4 // i n i t i a l i s é A V A N T le 1 er é l é m e n t de c o l l 5 while ( it . h a s N e x t () ) { // T a n t qu ’ il r e s t e des é l é m e n t s 6 E e = it . n e x t () ; // R é cup è re le p r o c h a i n é l é m e n t et a v a n c e 7 ... // T r a i t e r e 8 }

Les collections, comme les tableaux, peuvent aussi être parcourues à l’aide du mécanisme de « for each » :

1 for ( E e : c o l l ) { // P o u r t o u t é l é m e n t e de c o l l

2 ... // T r a i t e r e

3 }

Par rapport au parcours avec un itérateur, un for each traite systématiquement tous les éléments de la collection. L’itérateur permet aussi d’enlever un élément pendant le parcours (la classeIteratorpossède une méthode remove(), optionnelle, qui retire de la collection le dernier élément retourné parnext()).

3

Principales collections

Nous ne décrivons ici que les collections usuelles principales.

3.1

Séquences : List

L’interfaceList<E> définit une séquence d’éléments, indexés du 1erau dernier par leur position dans la séquence (un entier de 0 àsize() - 1). Les méthodes permettent d’insérer au début, à la fin, à une position précise. Lors d’une itération, les éléments sont naturellement parcourus dans l’ordre de la séquence. Les deux principales classes réalisant cette interface sont :

1. LinkedList<E>: basée sur une liste doublement chaînée, cette classe est intéressante en cas d’ajouts et suppressions en début ou milieu de séquence ;

1 // E x e m p l e : une L i n k e d L i s t de p o i n t s

2 L i n k e d L i s t < Point > l P o i n t s = new L i n k e d L i s t < Point >() ;

3 l P o i n t s . add (new P o i n t (0 , 0) ) ; // par d é faut , a j o u t en fin 4 l P o i n t s . a d d F i r s t (new P o i n t (1 , 1) ) ;

5 l P o i n t s . add (new P o i n t (2 , 2) ) ;

6 S y s t e m . out . p r i n t l n ( l P o i n t s ) ; // [(1 ,1) , (0 ,0) , (2 ,2) ]

7 l P o i n t s . r e m o v e (1) ; // enl è ve la v a l e u r en p o s i t i o n 1

8 S y s t e m . out . p r i n t l n ( l P o i n t s ) ; // [(1 ,1) , (2 ,2) ]

2. ArrayList<E>: basée sur un tableau redimensionnable et donc à cout constant pour les accès direct à un élément en fonction de sa position (ième). Par contre, les couts des insertions/suppressions en position quelconque sont linéaires (décalage des valeurs aux indices suivants).

1 // E x e m p l e : un A r r a y L i s t de C h a r a c t e r ( auto - b o x i n g sur des c h a r ) 2 A r r a y L i s t < C h a r a c t e r > l e t t r e s = new A r r a y L i s t < C h a r a c t e r >() ; 3 for (char c = ’ a ’; c <= ’ z ’; c ++) {

4 l e t t r e s . add ( c ) ; // a j o u t en fin

5 }

6 l e t t r e s . set (4 , ’ E ’) ; // r e m p l a c e la 5 è me l e t t r e par sa m a j u s c u l e 7 S y s t e m . out . p r i n t l n (" La 25 eme l e t t r e est " + l e t t r e s . get ( 2 4 ) ) ;

8 l e t t r e s . r e m o v e (6) ; // c o u t ! ( d e c a l a g e s ) 9 10 // On a f f i c h e les 10 p r e m i è res l e t t r e s 11 I t e r a t o r < C h a r a c t e r > it = l e t t r e s . i t e r a t o r () ; 12 int n = 0 ; 13 while ( it . h a s N e x t () && n ++ < 10) { 14 char c = it . n e x t () ; 15 S y s t e m . out . p r i n t ( c + " ") ; 16 } // a f f i c h a g e : a b c d E f h i j k

(4)

3.2

Files et piles : Queue, Deque

L’interfaceQueue<E> définit typiquement une file (FIFO), avec deux méthodesadd(E e)qui ajoute en fin etE remove()qui enlève et retourne le premier élément.

L’interfaceDeque<E> (Double Ended Queue) spécialise une Queue<E> avec des méthodes d’insertion, d’accès et de retrait en tête et queue de liste : addFirst, addLast, removeFirst, removeLast, getFirst,

getLast. Cet méthodes permettent notamment d’utiliserDeque comme une pile (LIFO), en considérant

pas exemple la tête comme le sommet de la pile.

La classe de référence réalisant ces interfaces estLinkedList<E>. Les opérations principales sont à coût constant O(1).

1 // Ex : f i l e ( F I F O ) de v a l e u r s e n t i è res

2 // n o t e z le Queue < Integer > et pas Queue < int >

3 // = > p o u r les t y p e s de base , il f a u t u t i l i s e r des c l a s s e s " w r a p p e r " 4 // ( Integer , Float , D o u b l e . . . )

5 Queue < Integer > f i l e = new L i n k e d L i s t < Integer > () ;

6 f i l e . add (1) ; 7 f i l e . add (2) ; 8 f i l e . add (3) ; 9 S y s t e m . out . p r i n t l n ( f i l e . r e m o v e () ) ; // a f f i c h e 1 10 f i l e . add (4) ; 11 while ( !f i l e . i s E m p t y () ) { 12 S y s t e m . out . p r i n t l n ( f i l e . r e m o v e () ) ; // a f f i c h e 2 , 3 p u i s 4 13 }

3.3

File à priorités

La classe PriorityQueue<E> est une file à priorité : l’ordre de sortie des éléments ne dépend plus de leur date d’insertion, comme une FIFO ou LIFO, mais d’une priorité entre éléments. En pratique les éléments doivent être munis d’une relation d’ordre, et l’élément le plus prioritaire (le prochain à sortir) est le plus petit selon cet ordre.

Deux solutions sont possibles pour définir cette relation d’ordre (un exemple est donné en annexeA) : 1. la classeEdes éléments peut réaliser l’interfaceComparable<E>, qui définit l’ordre « naturel » entre des instances de E. Elle doit donc redéfinir la méthode public int compareTo(E e) qui retourne une valeur négative/nulle/positive sithisest plus petit/égal/plus grand que e.

2. il est aussi possible de déléguer la comparaison de deux objets E à une tierce classe qui réalise l’interface Comparator<E>. Celle-ci définit une seule méthode : public int compare(E e1, E e2) qui retourne une valeur négative/nulle/positive sie1est plus petit/égal/plus grand que e2. Si une classe fille de Comparatorest donné à laPriorityQueue, c’est elle qui effectue la comparaison des éléments même si le typeEréaliseComparable<E>.

Cette seconde approche est surtout utilisée pour pouvoir comparer des éléments selon des critères différents. Il est par exemple possible de créer deux classes qui comparent des étudiants selon leur nom ou selon leur note de POO.

L’implantation de la classe PriorityQueue<E> repose sur un tas binaire. Les coûts des opérations d’insertion et d’accès/retrait de l’élément le plus prioritaire sont en O(log(n)). Attention par contre, la recherche ou la suppression d’un élément quelconque sont possibles mais en O(n).

3.4

Ensembles : Set

A la différence des séquences ou queues, un ensemble définit par l’interface Set<E>n’admet pas de doublons : un élément ne peut pas être présent deux fois dans la collection. Cette égalité entre éléments est testée via la méthodeboolean equals(Object o)héritée de la super classeObject, qui doit de ce fait être correctement redéfinie dans la classe Edes éléments duSet.

Ensemble quelconque La classe HashSet<E> réalise l’interface Set<E> avec une implémentation de type table de hachage. Le cout amorti des opérations principales (ajout, retrait, recherche) est en O(1). L’itération retourne bien toutes les valeurs mais dans un ordre quelconque.

(5)

En plus de redéfinirequals, les éléments doivent aussi redéfinir une autre méthode de la classeObject : public int hashCode(), qui doit retourner une clé de hachage entière. Cette méthode doit être cohérente avec la redéfinition de l’égalité : si deux objets sont égaux au sens deequals, alors leur méthodehashCode doit retourner la même valeur.

Ensemble ordonné La classeTreeSet<E>définit un ensemble dont les valeurs sont ordonnées. Il est donc nécessaire de munir les éléments d’une relation d’ordre pour pouvoir les comparer. Comme précédemment, deux solutions sont possibles :

1. la classeEdes éléments peut réaliser l’interfaceComparable<E>. C’est donc la méthodecompareTo qui est utilisée pour ordonner les éléments dans la collection.

2. un objet de typeComparator<E>peut être donné auTreeSet. C’est alors lui qui réalise la comparaison des éléments même si la classe EréaliseComparable<E>.

Quelle que soit la méthode utilisée, la comparaison doit être compatible avec l’égalite : sie1.equals(e2) (respectivement !equals) alors e1.compareTo(e2) et/ou compare(e1, e2)doivent retourner 0 (respecti-vement une valeur non nulle).

L’implantation de cette classe repose sur un arbre équilibré (de type rouge-noir), avec des coûts en O(log(n)) pour les opérations principales.

Un exemple avancé d’ensemble ordonné est disponible en annexeA.

4

Dictionnaires : Map

L’interfaceMap<K,V> spécifie des associations entre une clé de typeKet une valeur de type deV. Un Map ne peut pas contenir des clés identiques, et chaque clé n’est associée qu’à une et une seule valeur. Les opérations principales sont l’ajout d’un couple (put(K key, V value)), l’accès à une valeur via sa clé (V get(K key)), la recherche de clé ou de valeur, la suppression d’une valeur, etc.

L’interfaceSortedMap<K,V>étendMap<K,V>, en rajoutant une relation d’ordre sur les clés du dictionnaire. Deux classes principales existent :

1. HashMap<K,V>: une table avec hachage sur les clés ;

2. TreeMap<K,V>: un ensemble ordonné sur les clés (implanté là encore avec une arbre rouge-noir équilibré).

Comme pour lesSet, les méthodesequals,hashCodeainsi qu’une relation d’ordre doivent être correcte-ment définies, en particulier sur le typeKdes clés1.

Parcours UnMappeut être parcouru de différentes manières. En fait trois méthodes renvoient les clés et/ou les valeurs dans des collections, qui peuvent à leur tour être itérées :

— la méthodeCollection<V> values()retourne une collection (dont on ne connaît pas le type dyna-mique, mais ce n’est pas nécessaire) contenant toutes les valeurs.

— Set<K> keySet()retourne un ensemble contenant toutes les clés.

— Set<Map.Entry<K,V>> entrySet()retourne un ensemble de tous les couples<clé,valeur>. Ces couples sont de typeMap.Entry<K,V>, oùEntry<K,V>est une classe interne àMapfournissant principalement deux méthodesK getKey()etV getValue().

Pour unSortedMap, les collections ci-dessus sont ordonnées suivant l’ordre défini sur les clés. Un exemple deMapest disponible en annexeB.

1. Même si elles ne sont pas utilisées par toutes les collections, il est recommandé de toujours redéfinirhashCodeen même temps queequals, pour garantir la cohérence en cas d’utilisation d’une classe dans plusieurs collections.

(6)

A

Exemple d’ordonnancement

L’exemple ci-dessous, contenu dans ExempleOrdonnancement.java, montre l’utilisation d’un ensemble ordonnée TreeSet, avec notamment la redéfinition des méthodesequals ethashCodeainsi que l’utilisation des interfaces Iterableet Iterator

1 /*

2 * E x e m p l e d ’ u t i l i s a t i o n de C o m p a r a b l e et C o m p a r a t o r .

3 *

4 * On t r a v a i l l e sur les Daltons , d é f i n i s par l e u r nom et l e u r t a i l l e . 5 * Ils s o n t s t o c k é s d a n s un e n s e m b l e o r d o n n é , en u t i l i s a n t d i f f é r e n t s 6 * m o y e n s de d é f i n i r la r e l a t i o n d ’ o r d r e .

7 *

8 * 1. la c l a s s e D a l t o n p e u t r é a l i s e r l ’ i n t e r f a c e C o m p a r a b l e < Dalton >. E l l e d o i t 9 * d o n c d é f i n i r une m é t h o d e c o m p a r e T o ( D a l t o n ) qui c o m p a r e une i n s t a n c e de 10 * D a l t o n à un a u t r e D a l t o n d o n n é en p a r a m è tre .

11 * C e c i d é f i n i t " l ’ o r d r e n a t u r e l " p o u r c o m p a r e r d e u x o b j e t s de t y p e D a l t o n 12 * ( ici on o r d o n n e sur la taille , p u i s sur le nom à t a i l l e é g a l e )

13 *

14 * 2. on p e u t a u s s i d é l é g u e r la c o m p a r a i s o n à une t i e r c e classe , qui d é f i n i t 15 * s i m p l e m e n t c o m m e n t c o m p a r e r d e u x D a l t o n s .

16 * C e t t e c l a s s e d o i t r é a l i s e r l ’ i n t e r f a c e C o m p a r a t o r , et red é f i n i r une s e u l e 17 * m é t h o d e c o m p a r e ( Dalton , D a l t o n ) qui c o m p a r e d e u x o b j e t s .

18 * On p e u t cr é er un c o m p a r a t e u r p o u r c h a q u e o r d r e s o u h a i t é . Ici on en cr é e 19 * d e u x : c o m p a r a i s o n sur le nom u n i q u e m e n t et sur la t a i l l e u n i q u e m e n t . 20 * 21 * Les m é t h o d e s de c o m p a r a i s o n s e n t r e d e u x o b j e t o1 et o2 r e t o u r n e n t une 22 * v a l e u r e n t i è re n é g a t i v e si o1 < o2 , , n u l l e si o1 == o2 23 * ou p o s i t i v e si o1 > o2 . 24 */ 25 26 27 import j a v a . u t i l .* ; 28 29 30 public class E x e m p l e O r d o n n a n c e m e n t { 31

32 public static void m a i n ( S t r i n g [] a r g s ) {

33

34 // T r o i s e n s e m b l e s o r d o n n é s s u i v a n t un o r d r e d i f f é r e n t :

35 // - d a n s les d e u x p r e m i e r s cas , on d é l è gue la c o m p a r a i s o n à un o b j e t 36 // e x t e r n e de t y p e C o m p a r a t o r

37 // - d a n s le dernier , on u t i l i s e l ’ o r d r e n a t u r e l de la c l a s s e D a l t o n 38 S o r t e d S e t < Dalton > d a l t o n s P a r N o m = new TreeSet < Dalton > (new

C o m p a r a t e u r N o m () ) ;

39 S o r t e d S e t < Dalton > d a l t o n s P a r T a i l l e = new TreeSet < Dalton > (new C o m p a r a t e u r T a i l l e () ) ;

40 S o r t e d S e t < Dalton > d a l t o n s = new TreeSet < Dalton > () ; // o r d r e

n a t u r e l 41

42 D a l t o n joe = new D a l t o n (" Joe ", T a i l l e . P E T I T ) ; 43 D a l t o n j a c k = new D a l t o n (" J a c k ", T a i l l e . M O Y E N ) ;

44 D a l t o n w i l l i a m = new D a l t o n (" W i l l i a m ", T a i l l e . M O Y E N ) ; 45 D a l t o n a v e r e l l = new D a l t o n (" A v e r e l l ", T a i l l e . B E T E ) ; 46

47 // i n s e r t i o n ds un o r d r e q u e l c o n q u e , de t o u t e s fa cons c ’ est tri é 48 d a l t o n s P a r N o m . add ( w i l l i a m ) ;

49 d a l t o n s P a r N o m . add ( joe ) ;

50 d a l t o n s P a r N o m . add ( a v e r e l l ) ; 51 d a l t o n s P a r N o m . add ( j a c k ) ; 52

(7)

53 d a l t o n s P a r T a i l l e . add ( w i l l i a m ) ; 54 d a l t o n s P a r T a i l l e . add ( joe ) ; 55 d a l t o n s P a r T a i l l e . add ( a v e r e l l ) ; 56 d a l t o n s P a r T a i l l e . add ( j a c k ) ; 57 58 d a l t o n s . add ( w i l l i a m ) ; 59 d a l t o n s . add ( joe ) ; 60 d a l t o n s . add ( a v e r e l l ) ; 61 d a l t o n s . add ( j a c k ) ; 62

63 S y s t e m . out . p r i n t l n (" Les Daltons , o r d o n n é s par nom : ") ; 64 S y s t e m . out . p r i n t l n ( d a l t o n s P a r N o m ) ;

65 S y s t e m . out . p r i n t l n (" - > Bof . . . \ n ") ; 66

67 S y s t e m . out . p r i n t l n (" Les Daltons , o r d o n n é s par t a i l l e : " + d a l t o n s P a r T a i l l e ) ;

68 S y s t e m . out . p r i n t l n (" - > Argh , il en m a n q u e un ! ( ben oui , c ’ est un Set !) \ n ") ;

69

70 S y s t e m . out . p r i n t l n (" Les Daltons , t o u t c o u r t : " + d a l t o n s ) ; 71 S y s t e m . out . p r i n t l n (" - > L à c ’ est m i e u x !\n ") ; 72 73 S y s t e m . out . p r i n t l n (" \ n ( I ’ m a p o o r l o n e s o m e t e a c h e r . . . ) ") ; 74 } 75 76 } 77 78 79 80 e n u m T a i l l e { 81 PETIT , 82 MOYEN , 83 B E T E 84 } 85 86 /* * 87 * C l a s s Dalton , m u n i e d ’ un o r d r e n a t u r e l . 88 */

89 class D a l t o n implements C o m p a r a b l e < Dalton > {

90 private S t r i n g nom ;

91 private T a i l l e t a i l l e ; 92

93 public D a l t o n ( S t r i n g nom , T a i l l e t a i l l e ) {

94 this. nom = nom ;

95 this. t a i l l e = t a i l l e ; 96 } 97 98 public S t r i n g g e t N o m () { 99 return nom ; 100 } 101 102 public T a i l l e g e t T a i l l e () { 103 return t a i l l e ; 104 } 105 106 @ O v e r r i d e 107 public S t r i n g t o S t r i n g () { 108 return nom + (" ( ") + t a i l l e . t o S t r i n g () + " ) "; 109 } 110 111 /* *

(8)

112 * O r d r e n a t u r e l : c o m p a r a i s o n sur la t a i l l e d ’ abord , p u i s 113 * sur le nom . 114 * @ r e t u r n une v a l e u r n é g a t i v e / n u l l e / p o s i t i v e si t h i s est 115 * p l u s p e t i t / é gal / p l u s g r a n d que d . 116 */ 117 @ O v e r r i d e 118 public int c o m p a r e T o ( D a l t o n d ) { 119 if ( d == null) 120 throw new N u l l P o i n t e r E x c e p t i o n () ; 121 122 int dt = this. t a i l l e . o r d i n a l () - d . t a i l l e . o r d i n a l () ; // o r d r e ds l ’ e n u m 123 if ( dt < 0) { // t h i s < d 124 return -1 ; 125 } else if ( dt > 0) { // t h i s > d 126 return 1 ;

127 } else { // m ê me taille , on c o m p a r e sur le nom 128 // ( S t r i n g r e a l i s e C o m p a r a b l e < String >)

129 return this. nom . c o m p a r e T o ( d . nom ) ;

130 } 131 } 132 133 134 // A p a r t i r du m o m e n t o ù une c l a s s e r é a l i s e C o m p a r a b l e , il est f o r t e m e n t 135 // r e c o m m a n d é de red é f i n i r e q u a l s ( et h a s h C o d e ) de m a n i e r e coh é r e n t e 136 // par r a p p o r t à cet o r d r e : 137 // o1 . c o m p a r e T o ( o2 ) == 0 d o i t ê tre i d e n t i q u e à o1 . e q u a l s ( o2 ) 138 // si o1 . e q u a l s ( o2 ) == t r u e , a l o r s o1 . h a s h C o d e () == o2 . h a s h C o d e () 139 140 @ O v e r r i d e 141 public boolean e q u a l s ( O b j e c t o ) { 142 if ( o instanceof D a l t o n == false) // v e r i f i e a u s s i o != n u l l 143 return false; 144 145 D a l t o n d = ( D a l t o n ) o ;

146 return this. nom . e q u a l s ( d . nom ) && this. t a i l l e == d . t a i l l e ;

147 } 148 149 // D e u x i n s t a n c e i d e n t i q u e s , au s e n s d ’ e q u a l s et de c o m p a r e T o , 150 // d o i v e n t r e t o u r n e r un m ê me h a s h C o d e 151 @ O v e r r i d e 152 public int h a s h C o d e () {

153 // ici on d é l è gue au nom ( h a s h C o d e de S t r i n g est d é j à red é f i n i e )

154 return nom . h a s h C o d e () ; 155 } 156 } 157 158 159 /* * 160 * C l a s s e s e r v a n t à c o m p a r e r d e u x o b j e t s D a l t o n sur l e u r nom u n i q u e m e n t . 161 */

162 class C o m p a r a t e u r N o m implements C o m p a r a t o r < Dalton > { 163 164 @ O v e r r i d e 165 public int c o m p a r e ( D a l t o n d0 , D a l t o n d1 ) { 166 return d0 . g e t N o m () . c o m p a r e T o ( d1 . g e t N o m () ) ; 167 } 168 } 169 170 /* * 171 * C l a s s e s e r v a n t à c o m p a r e r d e u x o b j e t s D a l t o n sur l e u r t a i l l e u n i q u e m e n t . 172 */

(9)

173 class C o m p a r a t e u r T a i l l e implements C o m p a r a t o r < Dalton > { 174 175 @ O v e r r i d e 176 public int c o m p a r e ( D a l t o n d0 , D a l t o n d1 ) { 177 return d0 . g e t T a i l l e () . o r d i n a l () - d1 . g e t T a i l l e () . o r d i n a l () ; 178 } 179 }

Et voici la trace du programme : Les Daltons, ordonnés par nom :

[Averell (BETE), Jack (MOYEN), Joe (PETIT), William (MOYEN)] -> Bof...

Les Daltons, ordonnés par taille : [Joe (PETIT), William (MOYEN), Averell (BETE)] -> Argh, il en manque un ! (ben oui, c’est un Set donc pas de doublons !)

Les Daltons, tout court : [Joe (PETIT), Jack (MOYEN), William (MOYEN), Averell (BETE)]

-> Là c’est mieux !

(10)

B

Exemple d’utilisation d’un dictionnaire

Un exemple d’utilisation d’unHashMap.

1 import j a v a . u t i l .* ; 2

3

4 public class E x e m p l e M a p { 5

6 public static void m a i n ( S t r i n g [] a r g s ) {

7

8 // ex : d i c t i o n n a i r e a s s o c i a n t des é t u d i a n t s ( cl é , cha î ne ) 9 // à des n o t e s ( v a l e u r s e n t i è res )

10 Map < String , Integer > a n n u a i r e = new HashMap < String , Integer > () ;

11 12 S t r i n g mc = new S t r i n g (" M a t t h i e u ") ; 13 S t r i n g sb = new S t r i n g (" S y l v a i n ") ; 14 S t r i n g nc = new S t r i n g (" N i c o l a s ") ; 15 a n n u a i r e . put ( mc , 4) ; 16 a n n u a i r e . put ( sb , 18) ; 17 a n n u a i r e . put ( nc , 12) ; 18 a n n u a i r e . put ( mc , 14) ; // pas de d o u b l o n s , 19 // m a i s r e m p l a c e l ’ a n c i e n n e v a l e u r a s s o c i é e a mc 20 21 // et q u e l l e est la n o t e de C a t h e r i n e ? 22 I n t e g e r n o t e = a n n u a i r e . get (" C a t h e r i n e ") ; 23 S y s t e m . out . p r i n t l n (" La n o t e de C a t h e r i n e est : " + n o t e ) ; // n u l l ! 24 25 26 // a f f i c h a g e a v e c t o S t r i n g () ; o r d r e ? 27 S y s t e m . out . p r i n t l n (" L ’ a n n u a i r e c o n t i e n t : " + a n n u a i r e ) ; 28 29 // e n s e m b l e des cl é s , et des v a l e u r s 30 Set < String > c l e s = a n n u a i r e . k e y S e t () ; 31 S y s t e m . out . p r i n t l n (" Les cl é s s o n t : " + c l e s ) ; 32 33 // c o l l e c t i o n des v a l e u r s 34 C o l l e c t i o n < Integer > n o t e s = a n n u a i r e . v a l u e s () ; 35 S y s t e m . out . p r i n t l n (" Les v a l e u r s s o n t : " + n o t e s ) ; 36 37 // p a r c o u r s a v e c un it é r a t e u r sur les c o u p l e s 38 // ( pr é v o i r une a s p i r i n e p o u r la s y n t a x e . . . ) 39 S y s t e m . out . p r i n t l n (" Les c o u p l e s s o n t :") ;

40 Set < Map . Entry < String , Integer > > c o u p l e s = a n n u a i r e . e n t r y S e t () ; 41 I t e r a t o r < Map . Entry < String , Integer > > i t C o u p l e s = c o u p l e s . i t e r a t o r () ; 42 while ( i t C o u p l e s . h a s N e x t () ) {

43 Map . Entry < String , Integer > c o u p l e = i t C o u p l e s . n e x t () ;

44 S y s t e m . out . p r i n t l n (" \ t " + c o u p l e . g e t K e y () + " a la n o t e " + c o u p l e . g e t V a l u e () ) ; 45 } 46 47 } 48 }

Figure

Figure 1 – Hiérarchie des principales collections Java : des interfaces (spécifications purement abstraites) et les classes concrètes utilisables en pratique : ArrayList&lt;E&gt; , LinkedList&lt;E&gt; , PriorityQueue&lt;E&gt; , HashSet&lt;E&gt;

Références

Documents relatifs

(Au Québec, il y a actuelle- ment 46 ordres professionnels, le 46 e vient d'être créé, celui des criminologues. En France, il y en a à peine une quinzaine.) Il s’agissait donc

L’archive ouverte pluridisciplinaire HAL, est destinée au dépôt et à la diffusion de documents scientifiques de niveau recherche, publiés ou non, émanant des

L’archive ouverte pluridisciplinaire HAL, est destinée au dépôt et à la diffusion de documents scientifiques de niveau recherche, publiés ou non, émanant des

a) La qualité de la relation d'attachement joue un rôle modérateur sur l'association entre les pratiques parentales et les troubles du comportement:

Il s’agissait de former rapidement des ouvriers pour les industries d’armement, de faire face à l’explosion du chômage des jeunes et, à partir du régime de Vichy (10 juillet

Résumé Cet article présente un nouveau protocole d’apprentissage de la programmation dans lequel les séquences de travail sont structurées en cycles : d’abord

À travers deux études de cas, nous étudions les articulations entre le système didactique principal (classe de mathématiques) et le système didactique auxiliaire (regroupement

Un sac circule dans les familles, contenant un album ou un conte bilingue français et langue familiale, une clé USB avec la version numérique du livre (avec capsules sons)