Transcript L3-Langage_Java_files/LOO 10.COLLECTIONS
Slide 1
1
Java : Le Collections Framework (JCF)
Java Collections Framework :
Introduction
(diapo 2)
La JCF
Les interfaces
Les implémentations (classes)
Les interfaces Collection
Les classes Collection
Les interfaces Map
Les classes Map
Détails
Comment spécialiser une classe du JCF
Les Wrappers
(6)
(6)
(7)
(8)
(9)
(10)
(11)
(12)
(16)
(18)
Interopérabilité entre API
Compatibilité entre API Java
Guide de bon usage du JCF
(22)
(22)
(23)
Cours JAVA / Y.Laborde
Slide 2
2
JCF : Introduction (1)
Voir The Java Tutorials :
http://java.sun.com/docs/books/tutorial/collections/index.html
JCF = Java Collections Framework = Bibliothèque de classes Java spécialisées pour les collections
Le Java Collections Framework (Java SE 6) utilise abondamment des classes déclarées comme des
types génériques. Malgré une complexité apparente, ces classes sont très simples d’emploi.
Ex:
• public class ArrayList extends AbstractList implements List, RandomAccess, Cloneable, Serializable
• public abstract class AbstractList extends AbstractCollection implements List
• public interface List extends Collection
• public interface Collection extends Iterable
• public interface Iterable
Ici, nous supposons que l’usage de types génériques est connu.
Qu’est-ce qu’une collection (au sens général) ?
Une collection est simplement un objet qui regroupe de multiples éléments dans une unité unique – une
classe en Java.
Les collections sont utilisées pour ajouter, récupérer, manipuler et, plus généralement, pour communiquer
avec les éléments agrégés.
Typiquement, elles représentent des éléments de données qui forment naturellement un groupe, comme :
• une main de poker (une collection de cartes),
• un dossier de mail (une collection de messages),
• un répertoire de téléphone (une association de noms avec des numéros de téléphone).
ATTENTION : les collections n’ont été introduites (sous la forme d’un Framework) que
depuis la version 5.0 du JDK (J2SE 1.4) => (J2SE 1.5 =J2SE 5.0) => (Java SE 6).
Java SE 6: We recommend using the Java SE 6 specification even when writing programs for older releases.
Cours JAVA / Y.Laborde
Slide 3
3
JCF : Introduction (2)
Qu’est-ce qu’un Collections Framework ?
Un Collections Framework est une architecture unifiée pour représenter et manipuler des collections.
Tous les Collections Frameworks contiennent :
• des interfaces :
Ce sont des types abstraits qui permettent de manipuler les différents types de
collections, indépendamment des détails de leur représentation.
• des implémentations :
Ce sont les implémentations concrètes des interfaces de collections.
Ce sont des structures de données réutilisables.
• des algorithmes : Ce sont des méthodes qui réalisent des traitements spécifiques, comme la recherche
ou le tri, sur les objets qui implémentent les interfaces de collections.
Les algorithmes sont dits « polymorphiques » car les mêmes méthodes peuvent être utilisées à
partir de multiples implémentations différentes d’interfaces de collections appropriées.
Ce sont des fonctionnalités réutilisables.
En Orienté-Objet, les implémentations et les algorithmes sont réunis dans des classes organisées
hiérarchiquement. En Java, les interfaces sont un élément même du langage.
Exemple d’autres Collections Framworks :
- la C++ Standard Template Library (STL)
- la hiérarchie de collection de Smalltalk
En comparaison, le hiérarchie de collections de Java est beaucoup plus aisée d’apprentissage.
Cours JAVA / Y.Laborde
Slide 4
4
JCF : Introduction (3)
Quels sont les bénéfices du Java Collections Framework ?
D’après Sun System, le JCF apporte les avantages suivants :
• il réduit l’effort de programmation : en libérant le programmeur de toute la gestion des structures de
données et algorithmes ayant traits aux collections et donc en permettant de se concentrer sur les parties
importantes du programme.
• il augmente la vitesse et la qualité des programmes : les implémentations des structures et des
algorithmes du JCF sont de hautes performances et une grande qualité. Les différentes implémentations
sont interchangeables ; il est ainsi facile de passer d’un type de collection à un autre.
• il autorise l’interopérabilité avec les autres API : car les autres API peuvent échanger leur propres
collections par le biais des interfaces vernaculaires du JCF qui en effectue lui-même l’interopérabilité.
• il diminue l’effort d’apprentissage de nouvelles API : car les nouvelles API utiliseront maintenant
les mêmes collections Java en entrée et les fourniront également en sortie.
• il diminue l’effort de développement de nouvelles API : par le biais des interfaces et
implémentations standards de collections du JCF prévues pour la spécialisation.
• il décuple la réutilisabilité des programmes : de par la conformité aux interfaces standards de
collections du JCF, les nouvelles structures de données et aussi les nouveaux algorithmes sont naturellement
réutilisables sur les objets qui opèrent avec ses interfaces.
Cours JAVA / Y.Laborde
Slide 5
JCF : Introduction (4)
5
Nouvelles fonctionnalités du langage Java utilisées dans le cadre du JCF (J2SE 6.0)
Trois nouvelles fonctionnalités du langage Java accroissent sensiblement la puissance du JCF :
• généricité – ajout de l’inférence de typage qui certifie que les typages génériques sont correctement
résolus dès la compilation + élimination de la nécessité de coercitions explicites (cast) lors de la lecture
des éléments des collections,
• amélioration des boucles – nouvelle syntaxe adaptée à l’itération des collections et des tableaux (dite
instruction « for each » ou « enhanced for »),
Ex:
class EnhancedForDemo {
public static void main (String[] args){
int[] numbers = {1,2,3,4,5,6,7,8,9,10};
for (int item : numbers) {
System.out.println ( "Elément : " + item );
// itération sur les éléments du tableau
}
}
}
• Autoboxing/unboxing – c’est une partie de l’interopérabilité par la conversion automatique des types
primitifs (comme int) en leurs homologues objets (comme Integer) lors de leur insertion dans des
collections, et inversement lors de leur lecture depuis des collections.
Cours JAVA / Y.Laborde
Slide 6
6
JCF : Les interfaces*
* hors package java.util.concurrent
Les interfaces de collection sont le cœur du JCF ; elles permettent de manipuler les collections
indépendamment des détails de leurs représentations.
Les programmeurs devront être attentifs à ne conserver de référence sur une collection qu’au travers des
interfaces (et non au travers des classes vraies ou apparentes des collections).
Ex1: Set pioche = new HashSet ( );
// le HashSet est désormais vu comme un Set
Ex2: Collection pioche = new HashSet ( ); // le HashSet est désormais vu comme une Collection
Ici, Set et Collection sont bien sûr des interfaces !
Un Set est une sorte
spéciale de Collection ;
un SortedSet est une sorte
spéciale de Set, etc.
Les interfaces de collections
(core collection interfaces)
Note1: la hiérarchie est faite de deux hiérarchies principales distinctes.
L’une initiée par Collection, l’autre par Map.
Note2: toutes les interfaces de collection sont génériques.
ex: la déclaration de Collection est :
la déclaration de Map est :
public interface Collection...,
public interface Map...
Cours JAVA / Y.Laborde
Slide 7
7
JCF : Les implémentations*
* hors package java.util.concurrent
Implémentations
Interfaces
Tableau
variable
Arbre
équilibré
Liste
chaînée
(Hash Table)
(Resizable Array)
(Balanced Tree)
(Linked List)
HashSet,
Set
Table de
hachage
Hash Table
+
Linked List
LinkedHashSet
EnumSet
TreeSet
NavigableSet
ArrayList,
Vector,
Stack
List
PriorityQueue
Queue
LinkedList
ArrayDeque
Deque
Map
NavigableMap
HashMap,
IdentityHashMap
LinkedList
WeakHashMap
LinkedHashMap
TreeMap
Pour obtenir des classes synchronisées (thread-safe), utilisez les wrappers de la classe Collections
Voir The Java Tutorials : http://java.sun.com/docs/books/tutorial/collections/implementations/wrapper.html
Cours JAVA / Y.Laborde
Slide 8
8
JCF : Les interfaces Collection*
* hors package java.util.concurrent
Les interfaces Collection
Collection
Set
List
(core Collection interfaces)
Queue
lire [deck]
SortedSet
Deque
(en italique : interfaces qui ne sont jamais
implémentées directement dans le JCF 6.0)
NavigableSet
Interface
Commentaire
Accès
direct
Ordre maintenu
Doublons
admis
Élément
null admis
Collection
Collection générale - groupe d’objets
Non
/
/
/
Set
Ensemble - notion mathématique d’ensemble
Non
Non
Non
Oui (en gal)
SortedSet
Ensemble ordonné – ordre naturel ou à l’aide d’un
comparateur (interface Comparator)
Non
Oui
Non
Oui (en gal)
NavigableSet
Ensemble ordonné étendu – pour la recherche ("le(s)
précédent(s) de", "le(s) inférieur(s) à", etc.)
Non
Oui
Non
Non
conseillé
List
Séquence - collection ordonnée
Oui (en gal)
Oui
Oui (en gal)
Oui (en gal)
Queue
File d’attente – empilement/dépilement d’objets par
une des extrémités
Non
Oui: FIFO, LIFO,
autre
Oui
Non
Deque
File d’attente à double sens – op. aux 2 extrémités
Non
Oui: FIFO+LIFO
Oui
Non
conseillé
Cours JAVA / Y.Laborde
Slide 9
Pour
n’accepter
qu’un type
enum unique
(explicite ou
implicite)
JCF : Les classes Collection*
9
* hors package java.util.concurrent
Les interfaces Collection
Iterable
(core Collection interfaces)
Collection
Les classes Collection
(core Collection types)
AbstractCollection
AbstractSet
Set
EnumSet
>
HashSet
SortedSet
LinkHashSet
NavigableSet
TreeSet
List
AbstractList
RandomAccess
Vector
Stack
Queue
ArrayList
AbstractSequentialList
AbstractQueue
PriorityQueue
Deque
LinkedList
ArrayDeque
Cours JAVA / Y.Laborde
Slide 10
10
JCF : Les interfaces Map*
* hors package java.util.concurrent
Map
Les interfaces Map
Map.Entry
(core Map interfaces)
public static interface
SortedMap
(en italique : interfaces qui ne sont jamais
implémentées directement dans le JCF 6.0)
NavigableMap
Interface
Commentaire
Accès
direct
Ordre
maintenu
Doublons admis
Élément
null admis
Map
Dictionnaire – objets (V) rangées à l’aide de clés (K)
Non
Non
Seulement sur V
Oui (K ou V)
SortedMap
Dictionnaire ordonné par les clés – ordre naturel ou
à l’aide d’un comparateur (interface Comparator)
Non
Oui (K)
Seulement sur V
Oui (K ou V)
NavigableMap
Dictionnaire ordonné étendu – pour la recherche
("le(s) précédent(s) de", "le(s) inférieur(s) à", etc.)
Non
Oui (K)
Seulement sur V
Oui (K ou V)
L’interface Map.Entry (paire de clé/valeur ) :
La méthode Map.entrySet() renvoie une collection-view du Map (de type Set>), dont
les éléments sont des paires de clé/valeur. Attention, celles-ci restent liées à l’objet Map !
La seule façon d'obtenir une référence à une paires de clé/valeur est d’utiliser l'itérateur de cette collection.
Les objets Map.Entry ne sont valables que pour la durée de l'itération ; plus formellement, le
comportement d'une Map.Entry est indéfini si le Map lié a été modifié après que l'entrée ait été
renvoyé par l'itérateur, sauf par le biais de l'opération V setValue(V value) sur la paire de clé/valeur.
Cours JAVA / Y.Laborde
Slide 11
JCF : Les classes Map*
11
* hors package java.util.concurrent
Les interfaces Map
(core Map interfaces)
Les classes Map
Dictionary
Map
(core Map types)
Hashtable
Properties
AbstractMap
EnumMap
,V>
HashMap
SortedMap
LinkHashMap
IdentityHashMap
NavigableMap
TreeMap
WeakHashMap
Map.Entry
AbstractMap.SimpleEntry
public
public static
static
AbstractMap.SimpleImmutableEntry
Cours JAVA / Y.Laborde
Slide 12
12
JCF : Détails (1)
Voir The Java Tutorials :
http://java.sun.com/javase/6/docs/api/java/util/Collection.html
public interface Collection
C’est l’interface racine de la hiérarchie des collections.
Le JDK ne fournit aucune implémentation directe de l’interface Collection ; il fournit des implémentations de sousinterfaces plus spécifiques comme Set ou List.
L’interface Collection est typiquement utilisée pour envoyer ou manipuler des collections lorsque qu’on désire un
maximum de généralisation.
Toutes les implémentations du JCF qui implémentent Collection (toujours indirectement par le biais de sousinterfaces) fournissent deux constructeurs standards :
• un constructeur par défaut (sans argument) qui crée une collection vide,
• un constructeur avec un seul argument de type Collection qui crée une nouvelle collection avec les mêmes éléments
que son argument.
Ce dernier constructeur permet de transformer n’importe quelle collection en une implémentation d’un autre type !
Mais, comme les interfaces ne peuvent contenir de constructeurs, il n’y a aucun moyen de rendre obligatoire cette
convention. On ne peut donc compter que sur le fait que toutes les implémentations standards du JCF l’assument.
ATTENTION : Nombre de méthodes des interfaces de collection sont étiquetées « optional ».
Les implémentations peuvent ne pas fournir certaines de ces opérations ; si elles sont invoquées, elles déclenchent alors une exception à
l’exécution (UnsupportedOperationException).
Mais les implémentations standards du JCF supportent toutes les opérations optionnelles des interfaces de collection, et
n’ont aucune restriction sur les éléments qu’elles peuvent contenir.
Cours JAVA / Y.Laborde
Slide 13
13
JCF : Détails (2)
Voir Tutorials & Code Camps (par MageLang Institute):
http://java.sun.com/developer/onlineTraining/collections/Collectio
n.html#CollectionInterfacesAndClasses
Les interfaces de Collection d’ensembles :
Set, SortedSet et NavigableSet
Ces interfaces d’ensembles sont implémentées par les classes :
- EnumSet, HashSet, LinkedHashSet (: Set)
- TreeSet (: NavigableSet)
Cours JAVA / Y.Laborde
Slide 14
14
JCF : Détails (3)
Les interfaces de Collection de files
Queue et Deque
Voir Tutorials & Code Camps (par MageLang Institute):
http://java.sun.com/developer/onlineTraining/collections/Collectio
n.html#CollectionInterfacesAndClasses
d’attente :
Ces interfaces de files d’attente sont implémentées par les classes :
- PriorityQueue (: Queue)
- ArrayDeque et LinkedList (: Deque)
Les interfaces de Collection de séquences :
List
Ces interfaces de séquences sont implémentées
par les classes :
ArrayList, Vector, Stack et LinkedList (: List)
Cours JAVA / Y.Laborde
Slide 15
15
JCF : Détails (4)
Voir Tutorials & Code Camps (par MageLang Institute):
http://java.sun.com/developer/onlineTraining/collections/Collectio
n.html#CollectionInterfacesAndClasses
Les interfaces de Collection de dictionnaires :
Map et SortedMap et Deque
Autres interfaces utiles
Ces interfaces de dictionnaires sont implémentées par les classes :
- EnumMap, HashMap, IdentidyMap, WeakHashMap et LinkedHashMap (: Map)
- TreeMap (: SortedMap)
Cours JAVA / Y.Laborde
Slide 16
16
JCF : Spécialiser une classe du JCF (1)
Par exemple, comment disposer d’une liste de dominos qui permette de piocher ?
1) Par dérivation d’une classe du JCF
2) A l’aide d’une classe externe
public class DominoList
public class PiocheInList {
extends ArrayList {
// Méthode pioche
// Constructeurs
public static E piocher ( List laPioche) {
public DominoList ( ) {
if ( laPioche.isEmpty ( ) ) return null;
super ( );
int index = (int) (java.lang.Math.random ( ) * this.size ( ));
}
return laPioche.remove (index);
public DominoList (Collection c) {
}
super (c);
}
}
Comment
Piocher
unpeut-on
dominopiocher un domino ?
// Méthode pioche
Écrivez un codepioche
List
qui utilise
= new
la classe
ArrayList
PiocheInList.
( );
public Domino piocher ( ) {
pioche.add ( new Domino(1,2) ); etc.
if ( this.isEmpty ( ) ) return null;
if ( ! Pioche.isEmpty ( ) ) {
int index = (int) (java.lang.Math.random ( ) * this.size ( ));
Domino dominoPioché = PiocheInList.piocher (pioche);
return this.remove (index);
…}
}
* PiocheInList est générique.
}
* DominoList est très spécialisée.
Elle permet de piocher toutes sortes
Elle ne permet de supporter et de ne
d’objets mis en liste et pas seulement des
Comment
Piocher
unpeut-on
dominopiocher un dominopiocher
? que des dominos !
dominos !
* De plus, si on regarde une DominoList
Écrivez un code
DominoList
pioche
qui utilise
= new laDominoList
classe DominoList.
( );
* La pioche est naturellement vue
au travers de List, on ne peut
pioche.add ( new Domino(1,2) ); etc.
comme une List dans laquelle
plus piocher !
if ( ! Pioche.isEmpty ( ) ) {
on peut toujours piocher !
Domino dominoPioché = pioche.piocher ( ); …}
Cours JAVA / Y.Laborde
Slide 17
17
JCF : Spécialiser une classe du JCF (2)
3) Par encapsulation d’une classe du JCF
public class DominoList {
// Encapsulation d’une ArrayList
protected ArrayList laListe;
// Constructeurs
public DominoList ( ) {
this.laListe = new ArrayList ( ); }
public DominoList (Collection c) {
this.laListe = new ArrayList (c); }
// Méthode pioche
public Domino piocher ( ) {
if ( laListe.isEmpty ( ) ) return null;
int index = (int) (java.lang.Math.random ( ) * this.size ( ));
return laListe.remove (index);
}
// Méthodes de liste (à transférer à laListe)
public boolean add (Domino d) { return laListe.add (d); }
public boolean isEmpty ( ) { return laListe.isEmpty (); }
public int size ( ) { return laListe.size (); }
etc.
public Domino[] toArray ( ) {
return laListe.toArray (new Domino[ ]); }
}
Piocher un domino
(identique à la première méthode)
DominoList pioche = new DominoList ( );
pioche.add ( new Domino(1,2) ); etc.
if ( ! Pioche.isEmpty ( ) ) {
Domino dominoPioché = pioche.piocher ( ); …}
* Ici, il faudrait implémenter toutes les
méthodes de l’interface List pour en
faire une List !
* Mais, si on regarde une DominoList au
travers de List, on ne peut plus
piocher !
Chacune de ces 3
techniques a ses
avantages propres !
On pourra choisir
l’une ou l’autre.
Cours JAVA / Y.Laborde
Slide 18
18
JCF : Les Wrappers (1)
Voir The Java Tutorials :
http://java.sun.com/docs/books/tutorial/collections/implementations/wrapper.html
Les Wrappers permettent d’ajouter des fonctionnalités aux collections du JCF.
On trouve des wrappers pour 6 types de collections : Collection, List, Map, Set, SortedMap, SortedSet .
Ils permettent de :
o synchroniser des collections (les rendre thread-safe)
(ex: public static List synchronizedList(List list)),
o rendre des collections non-modifiables (read-only)
(ex: public static List unmodifiableList(List extends T> list)),
o rendre des collections type-safe (rendre impossible l’insertion d’éléments d’un mauvais type dans une collection)
(ex: public static List checkedList(List list, Class type)).
On trouve ces 18 méthodes static dans la classe Collections.
ATTENTION: Les opérations accessibles sur la collection synchronisée sont seulement celles de l’interface de
collection retournée par les wrappers.
Cours JAVA / Y.Laborde
Slide 19
19
JCF : Wrappers de synchronisation (2)
Voir The Java Tutorials :
http://java.sun.com/docs/books/tutorial/collections/implementations/wrapper.html
SYNCHRONISER des collections (les rendre thread-safe) :
La synchronisation permet de rendre des collections thread-safe. La collection retournée est du même type.
Méthodes statics de la classe Collections : public static List synchronizedList (List list), etc.
Mais il faudra faire attention à :
Ne manipuler la collection qu’au travers de celle retournée (et non au travers de la collection initiale qui reste liée) :
ex1: // OK car pas de référence conservée sur la collection liée
List listSync = Collections.synchronizedList ( new ArrayList( ) );
ex2: // DANGER - NOT OK car référence conservée sur la collection liée
List listInitiale = new ArrayList( );
// DANGER : même collection que listSync mais NON SYNCHRONISÉE
List listSync = Collections.synchronizedList ( listInitiale );
_____________________________________________________________________________________
Synchroniser manuellement les opérations d’itération sur la collection (comportement non déterministe sinon) :
ex1: Collection c = Collections.synchronizedCollection (myCollection);
synchronized (c) { for (Type e : c) foo (e); }
ex2: Map mSync = Collections.synchronizedMap ( new HashMap( ) );
…
Set sKeys = mSync.keySet();
…
synchronized (mSync) { while (KeyType k : sKeys) foo (k); } // ATTENTION: synchroniser mSync et non sKeys !
Cours JAVA / Y.Laborde
Slide 20
20
JCF : Wrappers de non modif/checked (3)
Voir The Java Tutorials :
http://java.sun.com/docs/books/tutorial/collections/implementations/wrapper.html
Rendre des collections NON MODIFIABLES (les rendre tread-only) :
Méthodes statics de la classe Collections : public static List unmodifiableList (List extends T> list), etc.
Cela permet soit de rendre une collection définitivement immutable, soit de n’offrir à certains clients que le
droit de lecture.
Toutes les opérations de modification de la collection lèvent l’exception UnsupportedOperationException.
Rendre des collections TYPE-SAFE (les rendre tread-only) :
Méthodes statics de la classe Collections : public static List checkedList (List list, Class type), etc.
Cela permet de rendre impossible l’insertion d’éléments d’un mauvais type dans une collection.
Toutes les tentatives d’insertion d’un élément d’un mauvais type lèvent l’exception ClassCastException.
Une application intéressante => le débugging :
ex: // CODE RELEASE
Collection c = new HashSet( );
// CODE DEBUG (code remplacé temporairement pour le debugging par :)
Collection c = Collections.checkedCollection ( new HashSet( ), String.class);
Cours JAVA / Y.Laborde
Slide 21
21
Interop : Compatibilité entre API Java (1)
Voir The Java Tutorials :
http://java.sun.com/docs/books/tutorial/collections/interoperability/compatibility.html
Compatibilité DESCENDANTE ( objets de 1.5 à + méthodes de 1.1 à 1.4 ) :
Lorsque vous utilisez une API qui renvoie des nouvelles interfaces de collections en tandem avec un autre API qui exige les
anciennes collections.
Pour réaliser leur interopération, vous devrez convertir les nouvelles collections en des anciennes collections.
Pour
ex1:
ex2:
Collection
=> Array
Collection my_new_coll = newMethod ( );
Collection my_new_coll = newMethod ( );
________________________________________________________________
Pour
ex1:
Collection
=> Vector
Collection my_new_coll = newMethod ( );
________________________________________________________________
Pour
HashTable
ex1:
Map my_new_map = newMethod ( );
________________________________________________________________
Pour
ex:
Collection
utiliser dans l’interface Collection : Object[] toArray ()
oldMethod ( my_new_coll.toArray ( ) );
oldMethod ( (String[]) my_new_coll.toArray (new String[0]) );
________________________________________________________________________________________
utiliser dans la classe Vector : public Vector (Collection extends E> c)
oldMethod ( new Vector (my_new_coll) );
________________________________________________________________________________________
utiliser dans la classe Vector :
public Hashtable (Map extends K,? extends V> t)
oldMethod ( new Hashtable (my_new_map) );
________________________________________________________________________________________
=> Enumeration
utiliser dans la classe Collections :
public static Enumeration enumeration (Collection c)
Collection my_new_coll = newMethod (arg);
oldMethod ( Collections.enumeration (my_new_coll) );
Cours JAVA / Y.Laborde
Slide 22
22
Interop : Compatibilité entre API Java (2)
Voir The Java Tutorials :
http://java.sun.com/docs/books/tutorial/collections/interoperability/compatibility.html
Compatibilité ASCENDANTE ( objets de 1.1 à 1.4 méthodes de 1.5 à + ) :
Lorsque vous utilisez une API qui renvoie des anciennes collections en tandem avec un autre API qui exige les nouvelles
interfaces de collections.
Pour réaliser leur interopération, vous devrez convertir les anciennes collections en des nouvelles collections.
Pour
ex:
Array
=> List ou Collection
Foo[] my_old_array = oldMethod (arg);
________________________________________________________________
Pour
ex:
Vector
Vector my_old_vector = oldMethod (arg);
________________________________________________________________
Pour
ex:
ex:
________________________________________________________________________________________
utiliser tel quel
newMethod ( my_old_vector );
________________________________________________________________________________________
HashTable
utiliser tel quel
Hashtable my_old_hashtable = oldMethod (arg);
newMethod ( my_old_hashtable );
________________________________________________________________
Pour
utiliser dans la classe Arrays : public static List asList (T... a)
newMethod ( Arrays.asList (my_old_array) );
Enumeration
________________________________________________________________________________________
=> Collection
utiliser dans la classe Collections :
public static ArrayList list (Enumeration e)
Enumeration my_old_enum = oldMethod (arg);
newMethod ( Collections.list (my_old_enum) );
Cours JAVA / Y.Laborde
Slide 23
23
Interop : Guide de bon usage du JCF
Voir The Java Tutorials :
http://java.sun.com/docs/books/tutorial/collections/interoperability/api-design.html
Règles de conception pour l’usage du JCF
Cette section donne quelques directives importantes qui permettent aux utilisateurs du JCF de concevoir des API* capables
d’interopérer sans nécessité d’ajustement avec toutes les autres API qui les suivraient également.
En somme, ces règles définissent ce que serait un « bon usager » des collections Java.
*
on parle ici d’API car on réfère à une conception modulaire, que ce soit pour une véritable API ou pour un programme.
i.e. on suppose que, lorsque l’on développe un programme, c’est avec l’idée d’une éventuelle réutilisation de certaines parties
(développées dans des packages et contenant un interfaçage spécifique tout comme une véritable API).
Concernant les PARAMÈTRES des méthodes (votre API contient une méthode qui exige une collection en entrée) :
1.ne jamais utiliser un type d’implémentation (classe) car cela va à l’encontre de l’intérêt d’un Framework basé sur les
interfaces, il faut donc déclarer le type du paramètre comme l’une des interfaces de collections ;
ex: ne pas demander un type HashSet mais une interface Set ou Collection
2.toujours utiliser l’INTERFACE LA MOINS SPÉCIFIQUE en regard de la fonctionnalité à assurer (les types Collection
et Map sont les plus génériques).
ex: ne pas demander une interface List ou Set si une interface Collection suffit
Concernant les TYPES RETOURNÉS (votre API contient une méthode qui fournit une collection en sortie) :
1.toujours utiliser l’INTERFACE LA PLUS SPÉCIFIQUE pour permettre à l’utilisateur de manipuler la collection avec le
maximum d’efficacité (règle opposée à celle des paramètres d'entrée) ;
ex: retourner un type SortedMap plutôt qu’un Map permet à l’utilisateur de bénéficier de plus de puissance
2.il est loisible de retourner :
• soit une interface de collection,
• une interface spécifique de votre API qui dérive une interface de collection,
• soit une classe spécifique de votre API qui implémente une interface de collection ;
ex: retourner une interface List ou une classe DominoList (qui fournit des méthodes utiles comme piocher un domino, …)
Cours JAVA / Y.Laborde
1
Java : Le Collections Framework (JCF)
Java Collections Framework :
Introduction
(diapo 2)
La JCF
Les interfaces
Les implémentations (classes)
Les interfaces Collection
Les classes Collection
Les interfaces Map
Les classes Map
Détails
Comment spécialiser une classe du JCF
Les Wrappers
(6)
(6)
(7)
(8)
(9)
(10)
(11)
(12)
(16)
(18)
Interopérabilité entre API
Compatibilité entre API Java
Guide de bon usage du JCF
(22)
(22)
(23)
Cours JAVA / Y.Laborde
Slide 2
2
JCF : Introduction (1)
Voir The Java Tutorials :
http://java.sun.com/docs/books/tutorial/collections/index.html
JCF = Java Collections Framework = Bibliothèque de classes Java spécialisées pour les collections
Le Java Collections Framework (Java SE 6) utilise abondamment des classes déclarées comme des
types génériques. Malgré une complexité apparente, ces classes sont très simples d’emploi.
Ex:
• public class ArrayList
• public abstract class AbstractList
• public interface List
• public interface Collection
• public interface Iterable
Ici, nous supposons que l’usage de types génériques est connu.
Qu’est-ce qu’une collection (au sens général) ?
Une collection est simplement un objet qui regroupe de multiples éléments dans une unité unique – une
classe en Java.
Les collections sont utilisées pour ajouter, récupérer, manipuler et, plus généralement, pour communiquer
avec les éléments agrégés.
Typiquement, elles représentent des éléments de données qui forment naturellement un groupe, comme :
• une main de poker (une collection de cartes),
• un dossier de mail (une collection de messages),
• un répertoire de téléphone (une association de noms avec des numéros de téléphone).
ATTENTION : les collections n’ont été introduites (sous la forme d’un Framework) que
depuis la version 5.0 du JDK (J2SE 1.4) => (J2SE 1.5 =J2SE 5.0) => (Java SE 6).
Java SE 6: We recommend using the Java SE 6 specification even when writing programs for older releases.
Cours JAVA / Y.Laborde
Slide 3
3
JCF : Introduction (2)
Qu’est-ce qu’un Collections Framework ?
Un Collections Framework est une architecture unifiée pour représenter et manipuler des collections.
Tous les Collections Frameworks contiennent :
• des interfaces :
Ce sont des types abstraits qui permettent de manipuler les différents types de
collections, indépendamment des détails de leur représentation.
• des implémentations :
Ce sont les implémentations concrètes des interfaces de collections.
Ce sont des structures de données réutilisables.
• des algorithmes : Ce sont des méthodes qui réalisent des traitements spécifiques, comme la recherche
ou le tri, sur les objets qui implémentent les interfaces de collections.
Les algorithmes sont dits « polymorphiques » car les mêmes méthodes peuvent être utilisées à
partir de multiples implémentations différentes d’interfaces de collections appropriées.
Ce sont des fonctionnalités réutilisables.
En Orienté-Objet, les implémentations et les algorithmes sont réunis dans des classes organisées
hiérarchiquement. En Java, les interfaces sont un élément même du langage.
Exemple d’autres Collections Framworks :
- la C++ Standard Template Library (STL)
- la hiérarchie de collection de Smalltalk
En comparaison, le hiérarchie de collections de Java est beaucoup plus aisée d’apprentissage.
Cours JAVA / Y.Laborde
Slide 4
4
JCF : Introduction (3)
Quels sont les bénéfices du Java Collections Framework ?
D’après Sun System, le JCF apporte les avantages suivants :
• il réduit l’effort de programmation : en libérant le programmeur de toute la gestion des structures de
données et algorithmes ayant traits aux collections et donc en permettant de se concentrer sur les parties
importantes du programme.
• il augmente la vitesse et la qualité des programmes : les implémentations des structures et des
algorithmes du JCF sont de hautes performances et une grande qualité. Les différentes implémentations
sont interchangeables ; il est ainsi facile de passer d’un type de collection à un autre.
• il autorise l’interopérabilité avec les autres API : car les autres API peuvent échanger leur propres
collections par le biais des interfaces vernaculaires du JCF qui en effectue lui-même l’interopérabilité.
• il diminue l’effort d’apprentissage de nouvelles API : car les nouvelles API utiliseront maintenant
les mêmes collections Java en entrée et les fourniront également en sortie.
• il diminue l’effort de développement de nouvelles API : par le biais des interfaces et
implémentations standards de collections du JCF prévues pour la spécialisation.
• il décuple la réutilisabilité des programmes : de par la conformité aux interfaces standards de
collections du JCF, les nouvelles structures de données et aussi les nouveaux algorithmes sont naturellement
réutilisables sur les objets qui opèrent avec ses interfaces.
Cours JAVA / Y.Laborde
Slide 5
JCF : Introduction (4)
5
Nouvelles fonctionnalités du langage Java utilisées dans le cadre du JCF (J2SE 6.0)
Trois nouvelles fonctionnalités du langage Java accroissent sensiblement la puissance du JCF :
• généricité – ajout de l’inférence de typage qui certifie que les typages génériques sont correctement
résolus dès la compilation + élimination de la nécessité de coercitions explicites (cast) lors de la lecture
des éléments des collections,
• amélioration des boucles – nouvelle syntaxe adaptée à l’itération des collections et des tableaux (dite
instruction « for each » ou « enhanced for »),
Ex:
class EnhancedForDemo {
public static void main (String[] args){
int[] numbers = {1,2,3,4,5,6,7,8,9,10};
for (int item : numbers) {
System.out.println ( "Elément : " + item );
// itération sur les éléments du tableau
}
}
}
• Autoboxing/unboxing – c’est une partie de l’interopérabilité par la conversion automatique des types
primitifs (comme int) en leurs homologues objets (comme Integer) lors de leur insertion dans des
collections, et inversement lors de leur lecture depuis des collections.
Cours JAVA / Y.Laborde
Slide 6
6
JCF : Les interfaces*
* hors package java.util.concurrent
Les interfaces de collection sont le cœur du JCF ; elles permettent de manipuler les collections
indépendamment des détails de leurs représentations.
Les programmeurs devront être attentifs à ne conserver de référence sur une collection qu’au travers des
interfaces (et non au travers des classes vraies ou apparentes des collections).
Ex1: Set
// le HashSet est désormais vu comme un Set
Ex2: Collection
Ici, Set
Un Set est une sorte
spéciale de Collection ;
un SortedSet est une sorte
spéciale de Set, etc.
Les interfaces de collections
(core collection interfaces)
Note1: la hiérarchie est faite de deux hiérarchies principales distinctes.
L’une initiée par Collection, l’autre par Map.
Note2: toutes les interfaces de collection sont génériques.
ex: la déclaration de Collection est :
la déclaration de Map est :
public interface Collection
public interface Map
Cours JAVA / Y.Laborde
Slide 7
7
JCF : Les implémentations*
* hors package java.util.concurrent
Implémentations
Interfaces
Tableau
variable
Arbre
équilibré
Liste
chaînée
(Hash Table)
(Resizable Array)
(Balanced Tree)
(Linked List)
HashSet,
Set
Table de
hachage
Hash Table
+
Linked List
LinkedHashSet
EnumSet
TreeSet
NavigableSet
ArrayList,
Vector,
Stack
List
PriorityQueue
Queue
LinkedList
ArrayDeque
Deque
Map
NavigableMap
HashMap,
IdentityHashMap
LinkedList
WeakHashMap
LinkedHashMap
TreeMap
Pour obtenir des classes synchronisées (thread-safe), utilisez les wrappers de la classe Collections
Voir The Java Tutorials : http://java.sun.com/docs/books/tutorial/collections/implementations/wrapper.html
Cours JAVA / Y.Laborde
Slide 8
8
JCF : Les interfaces Collection*
* hors package java.util.concurrent
Les interfaces Collection
Collection
Set
List
(core Collection interfaces)
Queue
lire [deck]
SortedSet
Deque
(en italique : interfaces qui ne sont jamais
implémentées directement dans le JCF 6.0)
NavigableSet
Interface
Commentaire
Accès
direct
Ordre maintenu
Doublons
admis
Élément
null admis
Collection
Collection générale - groupe d’objets
Non
/
/
/
Set
Ensemble - notion mathématique d’ensemble
Non
Non
Non
Oui (en gal)
SortedSet
Ensemble ordonné – ordre naturel ou à l’aide d’un
comparateur (interface Comparator)
Non
Oui
Non
Oui (en gal)
NavigableSet
Ensemble ordonné étendu – pour la recherche ("le(s)
précédent(s) de", "le(s) inférieur(s) à", etc.)
Non
Oui
Non
Non
conseillé
List
Séquence - collection ordonnée
Oui (en gal)
Oui
Oui (en gal)
Oui (en gal)
Queue
File d’attente – empilement/dépilement d’objets par
une des extrémités
Non
Oui: FIFO, LIFO,
autre
Oui
Non
Deque
File d’attente à double sens – op. aux 2 extrémités
Non
Oui: FIFO+LIFO
Oui
Non
conseillé
Cours JAVA / Y.Laborde
Slide 9
Pour
n’accepter
qu’un type
enum unique
(explicite ou
implicite)
JCF : Les classes Collection*
9
* hors package java.util.concurrent
Les interfaces Collection
Iterable
(core Collection interfaces)
Collection
Les classes Collection
(core Collection types)
AbstractCollection
AbstractSet
Set
EnumSet
HashSet
SortedSet
LinkHashSet
NavigableSet
TreeSet
List
AbstractList
RandomAccess
Vector
Stack
Queue
ArrayList
AbstractSequentialList
AbstractQueue
PriorityQueue
Deque
LinkedList
ArrayDeque
Cours JAVA / Y.Laborde
Slide 10
10
JCF : Les interfaces Map*
* hors package java.util.concurrent
Map
Les interfaces Map
Map.Entry
(core Map interfaces)
public static interface
SortedMap
(en italique : interfaces qui ne sont jamais
implémentées directement dans le JCF 6.0)
NavigableMap
Interface
Commentaire
Accès
direct
Ordre
maintenu
Doublons admis
Élément
null admis
Map
Dictionnaire – objets (V) rangées à l’aide de clés (K)
Non
Non
Seulement sur V
Oui (K ou V)
SortedMap
Dictionnaire ordonné par les clés – ordre naturel ou
à l’aide d’un comparateur (interface Comparator)
Non
Oui (K)
Seulement sur V
Oui (K ou V)
NavigableMap
Dictionnaire ordonné étendu – pour la recherche
("le(s) précédent(s) de", "le(s) inférieur(s) à", etc.)
Non
Oui (K)
Seulement sur V
Oui (K ou V)
L’interface Map.Entry
La méthode Map.entrySet() renvoie une collection-view du Map (de type Set
les éléments sont des paires de clé/valeur. Attention, celles-ci restent liées à l’objet Map !
La seule façon d'obtenir une référence à une paires de clé/valeur est d’utiliser l'itérateur de cette collection.
Les objets Map.Entry
comportement d'une Map.Entry
renvoyé par l'itérateur, sauf par le biais de l'opération V setValue(V value) sur la paire de clé/valeur.
Cours JAVA / Y.Laborde
Slide 11
JCF : Les classes Map*
11
* hors package java.util.concurrent
Les interfaces Map
(core Map interfaces)
Les classes Map
Dictionary
Map
(core Map types)
Hashtable
Properties
AbstractMap
EnumMap
HashMap
SortedMap
LinkHashMap
IdentityHashMap
NavigableMap
TreeMap
WeakHashMap
Map.Entry
AbstractMap.SimpleEntry
public
public static
static
AbstractMap.SimpleImmutableEntry
Cours JAVA / Y.Laborde
Slide 12
12
JCF : Détails (1)
Voir The Java Tutorials :
http://java.sun.com/javase/6/docs/api/java/util/Collection.html
public interface Collection
C’est l’interface racine de la hiérarchie des collections.
Le JDK ne fournit aucune implémentation directe de l’interface Collection ; il fournit des implémentations de sousinterfaces plus spécifiques comme Set ou List.
L’interface Collection est typiquement utilisée pour envoyer ou manipuler des collections lorsque qu’on désire un
maximum de généralisation.
Toutes les implémentations du JCF qui implémentent Collection (toujours indirectement par le biais de sousinterfaces) fournissent deux constructeurs standards :
• un constructeur par défaut (sans argument) qui crée une collection vide,
• un constructeur avec un seul argument de type Collection qui crée une nouvelle collection avec les mêmes éléments
que son argument.
Ce dernier constructeur permet de transformer n’importe quelle collection en une implémentation d’un autre type !
Mais, comme les interfaces ne peuvent contenir de constructeurs, il n’y a aucun moyen de rendre obligatoire cette
convention. On ne peut donc compter que sur le fait que toutes les implémentations standards du JCF l’assument.
ATTENTION : Nombre de méthodes des interfaces de collection sont étiquetées « optional ».
Les implémentations peuvent ne pas fournir certaines de ces opérations ; si elles sont invoquées, elles déclenchent alors une exception à
l’exécution (UnsupportedOperationException).
Mais les implémentations standards du JCF supportent toutes les opérations optionnelles des interfaces de collection, et
n’ont aucune restriction sur les éléments qu’elles peuvent contenir.
Cours JAVA / Y.Laborde
Slide 13
13
JCF : Détails (2)
Voir Tutorials & Code Camps (par MageLang Institute):
http://java.sun.com/developer/onlineTraining/collections/Collectio
n.html#CollectionInterfacesAndClasses
Les interfaces de Collection d’ensembles :
Set, SortedSet et NavigableSet
Ces interfaces d’ensembles sont implémentées par les classes :
- EnumSet, HashSet, LinkedHashSet (: Set)
- TreeSet (: NavigableSet)
Cours JAVA / Y.Laborde
Slide 14
14
JCF : Détails (3)
Les interfaces de Collection de files
Queue et Deque
Voir Tutorials & Code Camps (par MageLang Institute):
http://java.sun.com/developer/onlineTraining/collections/Collectio
n.html#CollectionInterfacesAndClasses
d’attente :
Ces interfaces de files d’attente sont implémentées par les classes :
- PriorityQueue (: Queue)
- ArrayDeque et LinkedList (: Deque)
Les interfaces de Collection de séquences :
List
Ces interfaces de séquences sont implémentées
par les classes :
ArrayList, Vector, Stack et LinkedList (: List)
Cours JAVA / Y.Laborde
Slide 15
15
JCF : Détails (4)
Voir Tutorials & Code Camps (par MageLang Institute):
http://java.sun.com/developer/onlineTraining/collections/Collectio
n.html#CollectionInterfacesAndClasses
Les interfaces de Collection de dictionnaires :
Map et SortedMap et Deque
Autres interfaces utiles
Ces interfaces de dictionnaires sont implémentées par les classes :
- EnumMap, HashMap, IdentidyMap, WeakHashMap et LinkedHashMap (: Map)
- TreeMap (: SortedMap)
Cours JAVA / Y.Laborde
Slide 16
16
JCF : Spécialiser une classe du JCF (1)
Par exemple, comment disposer d’une liste de dominos qui permette de piocher ?
1) Par dérivation d’une classe du JCF
2) A l’aide d’une classe externe
public class DominoList
public class PiocheInList {
extends ArrayList
// Méthode pioche
// Constructeurs
public static
public DominoList ( ) {
if ( laPioche.isEmpty ( ) ) return null;
super ( );
int index = (int) (java.lang.Math.random ( ) * this.size ( ));
}
return laPioche.remove (index);
public DominoList (Collection
}
super (c);
}
}
Comment
Piocher
unpeut-on
dominopiocher un domino ?
// Méthode pioche
Écrivez un codepioche
List
qui utilise
= new
la classe
ArrayList
PiocheInList.
( );
public Domino piocher ( ) {
pioche.add ( new Domino(1,2) ); etc.
if ( this.isEmpty ( ) ) return null;
if ( ! Pioche.isEmpty ( ) ) {
int index = (int) (java.lang.Math.random ( ) * this.size ( ));
Domino dominoPioché = PiocheInList.piocher (pioche);
return this.remove (index);
…}
}
* PiocheInList est générique.
}
* DominoList est très spécialisée.
Elle permet de piocher toutes sortes
Elle ne permet de supporter et de ne
d’objets mis en liste et pas seulement des
Comment
Piocher
unpeut-on
dominopiocher un dominopiocher
? que des dominos !
dominos !
* De plus, si on regarde une DominoList
Écrivez un code
DominoList
pioche
qui utilise
= new laDominoList
classe DominoList.
( );
* La pioche est naturellement vue
au travers de List
pioche.add ( new Domino(1,2) ); etc.
comme une List
plus piocher !
if ( ! Pioche.isEmpty ( ) ) {
on peut toujours piocher !
Domino dominoPioché = pioche.piocher ( ); …}
Cours JAVA / Y.Laborde
Slide 17
17
JCF : Spécialiser une classe du JCF (2)
3) Par encapsulation d’une classe du JCF
public class DominoList {
// Encapsulation d’une ArrayList
protected ArrayList
// Constructeurs
public DominoList ( ) {
this.laListe = new ArrayList
public DominoList (Collection
this.laListe = new ArrayList
// Méthode pioche
public Domino piocher ( ) {
if ( laListe.isEmpty ( ) ) return null;
int index = (int) (java.lang.Math.random ( ) * this.size ( ));
return laListe.remove (index);
}
// Méthodes de liste (à transférer à laListe)
public boolean add (Domino d) { return laListe.add (d); }
public boolean isEmpty ( ) { return laListe.isEmpty (); }
public int size ( ) { return laListe.size (); }
etc.
public Domino[] toArray ( ) {
return laListe.toArray (new Domino[ ]); }
}
Piocher un domino
(identique à la première méthode)
DominoList pioche = new DominoList ( );
pioche.add ( new Domino(1,2) ); etc.
if ( ! Pioche.isEmpty ( ) ) {
Domino dominoPioché = pioche.piocher ( ); …}
* Ici, il faudrait implémenter toutes les
méthodes de l’interface List
faire une List
* Mais, si on regarde une DominoList au
travers de List
piocher !
Chacune de ces 3
techniques a ses
avantages propres !
On pourra choisir
l’une ou l’autre.
Cours JAVA / Y.Laborde
Slide 18
18
JCF : Les Wrappers (1)
Voir The Java Tutorials :
http://java.sun.com/docs/books/tutorial/collections/implementations/wrapper.html
Les Wrappers permettent d’ajouter des fonctionnalités aux collections du JCF.
On trouve des wrappers pour 6 types de collections : Collection, List, Map, Set, SortedMap, SortedSet .
Ils permettent de :
o synchroniser des collections (les rendre thread-safe)
(ex: public static
o rendre des collections non-modifiables (read-only)
(ex: public static
o rendre des collections type-safe (rendre impossible l’insertion d’éléments d’un mauvais type dans une collection)
(ex: public static
On trouve ces 18 méthodes static dans la classe Collections.
ATTENTION: Les opérations accessibles sur la collection synchronisée sont seulement celles de l’interface de
collection retournée par les wrappers.
Cours JAVA / Y.Laborde
Slide 19
19
JCF : Wrappers de synchronisation (2)
Voir The Java Tutorials :
http://java.sun.com/docs/books/tutorial/collections/implementations/wrapper.html
SYNCHRONISER des collections (les rendre thread-safe) :
La synchronisation permet de rendre des collections thread-safe. La collection retournée est du même type.
Méthodes statics de la classe Collections : public static
Mais il faudra faire attention à :
Ne manipuler la collection qu’au travers de celle retournée (et non au travers de la collection initiale qui reste liée) :
ex1: // OK car pas de référence conservée sur la collection liée
List
ex2: // DANGER - NOT OK car référence conservée sur la collection liée
List
// DANGER : même collection que listSync mais NON SYNCHRONISÉE
List
_____________________________________________________________________________________
Synchroniser manuellement les opérations d’itération sur la collection (comportement non déterministe sinon) :
ex1: Collection
synchronized (c) { for (Type e : c) foo (e); }
ex2: Map
…
Set
…
synchronized (mSync) { while (KeyType k : sKeys) foo (k); } // ATTENTION: synchroniser mSync et non sKeys !
Cours JAVA / Y.Laborde
Slide 20
20
JCF : Wrappers de non modif/checked (3)
Voir The Java Tutorials :
http://java.sun.com/docs/books/tutorial/collections/implementations/wrapper.html
Rendre des collections NON MODIFIABLES (les rendre tread-only) :
Méthodes statics de la classe Collections : public static
Cela permet soit de rendre une collection définitivement immutable, soit de n’offrir à certains clients que le
droit de lecture.
Toutes les opérations de modification de la collection lèvent l’exception UnsupportedOperationException.
Rendre des collections TYPE-SAFE (les rendre tread-only) :
Méthodes statics de la classe Collections : public static
Cela permet de rendre impossible l’insertion d’éléments d’un mauvais type dans une collection.
Toutes les tentatives d’insertion d’un élément d’un mauvais type lèvent l’exception ClassCastException.
Une application intéressante => le débugging :
ex: // CODE RELEASE
Collection
// CODE DEBUG (code remplacé temporairement pour le debugging par :)
Collection
Cours JAVA / Y.Laborde
Slide 21
21
Interop : Compatibilité entre API Java (1)
Voir The Java Tutorials :
http://java.sun.com/docs/books/tutorial/collections/interoperability/compatibility.html
Compatibilité DESCENDANTE ( objets de 1.5 à + méthodes de 1.1 à 1.4 ) :
Lorsque vous utilisez une API qui renvoie des nouvelles interfaces de collections en tandem avec un autre API qui exige les
anciennes collections.
Pour réaliser leur interopération, vous devrez convertir les nouvelles collections en des anciennes collections.
Pour
ex1:
ex2:
Collection
=> Array
Collection my_new_coll = newMethod ( );
Collection my_new_coll = newMethod ( );
________________________________________________________________
Pour
ex1:
Collection
=> Vector
Collection my_new_coll = newMethod ( );
________________________________________________________________
Pour
HashTable
ex1:
Map my_new_map = newMethod ( );
________________________________________________________________
Pour
ex:
Collection
utiliser dans l’interface Collection : Object[] toArray ()
oldMethod ( my_new_coll.toArray ( ) );
oldMethod ( (String[]) my_new_coll.toArray (new String[0]) );
________________________________________________________________________________________
utiliser dans la classe Vector : public Vector (Collection extends E> c)
oldMethod ( new Vector (my_new_coll) );
________________________________________________________________________________________
utiliser dans la classe Vector :
public Hashtable (Map extends K,? extends V> t)
oldMethod ( new Hashtable (my_new_map) );
________________________________________________________________________________________
=> Enumeration
utiliser dans la classe Collections :
public static
Collection my_new_coll = newMethod (arg);
oldMethod ( Collections.enumeration (my_new_coll) );
Cours JAVA / Y.Laborde
Slide 22
22
Interop : Compatibilité entre API Java (2)
Voir The Java Tutorials :
http://java.sun.com/docs/books/tutorial/collections/interoperability/compatibility.html
Compatibilité ASCENDANTE ( objets de 1.1 à 1.4 méthodes de 1.5 à + ) :
Lorsque vous utilisez une API qui renvoie des anciennes collections en tandem avec un autre API qui exige les nouvelles
interfaces de collections.
Pour réaliser leur interopération, vous devrez convertir les anciennes collections en des nouvelles collections.
Pour
ex:
Array
=> List ou Collection
Foo[] my_old_array = oldMethod (arg);
________________________________________________________________
Pour
ex:
Vector
Vector my_old_vector = oldMethod (arg);
________________________________________________________________
Pour
ex:
ex:
________________________________________________________________________________________
utiliser tel quel
newMethod ( my_old_vector );
________________________________________________________________________________________
HashTable
utiliser tel quel
Hashtable my_old_hashtable = oldMethod (arg);
newMethod ( my_old_hashtable );
________________________________________________________________
Pour
utiliser dans la classe Arrays : public static
newMethod ( Arrays.asList (my_old_array) );
Enumeration
________________________________________________________________________________________
=> Collection
utiliser dans la classe Collections :
public static
Enumeration my_old_enum = oldMethod (arg);
newMethod ( Collections.list (my_old_enum) );
Cours JAVA / Y.Laborde
Slide 23
23
Interop : Guide de bon usage du JCF
Voir The Java Tutorials :
http://java.sun.com/docs/books/tutorial/collections/interoperability/api-design.html
Règles de conception pour l’usage du JCF
Cette section donne quelques directives importantes qui permettent aux utilisateurs du JCF de concevoir des API* capables
d’interopérer sans nécessité d’ajustement avec toutes les autres API qui les suivraient également.
En somme, ces règles définissent ce que serait un « bon usager » des collections Java.
*
on parle ici d’API car on réfère à une conception modulaire, que ce soit pour une véritable API ou pour un programme.
i.e. on suppose que, lorsque l’on développe un programme, c’est avec l’idée d’une éventuelle réutilisation de certaines parties
(développées dans des packages et contenant un interfaçage spécifique tout comme une véritable API).
Concernant les PARAMÈTRES des méthodes (votre API contient une méthode qui exige une collection en entrée) :
1.ne jamais utiliser un type d’implémentation (classe) car cela va à l’encontre de l’intérêt d’un Framework basé sur les
interfaces, il faut donc déclarer le type du paramètre comme l’une des interfaces de collections ;
ex: ne pas demander un type HashSet mais une interface Set ou Collection
2.toujours utiliser l’INTERFACE LA MOINS SPÉCIFIQUE en regard de la fonctionnalité à assurer (les types Collection
et Map sont les plus génériques).
ex: ne pas demander une interface List ou Set si une interface Collection suffit
Concernant les TYPES RETOURNÉS (votre API contient une méthode qui fournit une collection en sortie) :
1.toujours utiliser l’INTERFACE LA PLUS SPÉCIFIQUE pour permettre à l’utilisateur de manipuler la collection avec le
maximum d’efficacité (règle opposée à celle des paramètres d'entrée) ;
ex: retourner un type SortedMap plutôt qu’un Map permet à l’utilisateur de bénéficier de plus de puissance
2.il est loisible de retourner :
• soit une interface de collection,
• une interface spécifique de votre API qui dérive une interface de collection,
• soit une classe spécifique de votre API qui implémente une interface de collection ;
ex: retourner une interface List
Cours JAVA / Y.Laborde