( JCF ) Java Collections Framework - Cours JAVA / Y.Laborde ...

powersmoneySoftware and s/w Development

Jul 14, 2012 (5 years and 1 month ago)

404 views

1
Cours JAVA / Y.Laborde
Java : Le
Collections Framework
(JCF)
Java Collections Framework
:



Introduction

(diapo 2)


La JCF

(6)


Les interfaces

(6)


Les implémentations (classes)

(7)


Les interfaces
Collection

(8)



Les classes
Collection

(9)



Les interfaces
Map

(10)



Les classes
Map

(11)



Détails

(12)



Comment spécialiser une classe du JCF

(16)



Les Wrappers

(18)


Interopérabilité entre API

(22)


Compatibilité entre API Java

(22)


Guide de bon usage du JCF

(23)
2
JCF :
Introduction
(1)

Cours JAVA / Y.Laborde
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<E>

extends
AbstractList<E>
implements
List<E>
, RandomAccess, Cloneable, Serializable

• public abstract class
AbstractList<E>
extends
AbstractCollection<E>
implements
List<E>

• public interface
List<E>
extends
Collection<E>

• public interface
Collection<E>

extends
Iterable<E>

• public interface
Iterable<T>
Ici, nous supposons que l’usage de types génériques est connu.
Qu’est-ce qu’une collection (au sens général) ?
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

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.

3
JCF :
Introduction
(2)

Cours JAVA / Y.Laborde
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.
4
JCF :
Introduction
(3)

Cours JAVA / Y.Laborde
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.
5
JCF :
Introduction
(4)

Cours JAVA / Y.Laborde
Trois nouvelles fonctionnalités du langage Java accroissent sensiblement la puissance du JCF :
Nouvelles fonctionnalités du langage Java utilisées dans le cadre du JCF
(J2SE 6.0)

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)
{
// itération sur les éléments du tableau
System.out.println ( "Elément : " + item );
}
}
}

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.
6
JCF :
Les interfaces*

Cours JAVA / Y.Laborde
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<Domino>
pioche = new
HashSet<Domino>
( );
// le HashSet est désormais vu comme un Set
Ex2:
Collection<Domino>
pioche = new
HashSet<Domino>
( );
// le HashSet est désormais vu comme une Collection
Ici, Set<E> et Collection<E> sont bien sûr des interfaces !
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 :

public interface
Collection<E>
...
,


la déclaration de
Map
est :

public interface
Map<K,V>
...
Un
Set
est une sorte
spéciale de
Collection
;
un
SortedSet
est une sorte
spéciale de
Set
, etc.

*
hors package
java.util.concurrent

7
JCF :
Les implémentations*

Cours JAVA / Y.Laborde

Interfaces
Implémentations
Table de
hachage
(Hash Table)
Tableau
variable
(Resizable Array)
Arbre
équilibré
(Balanced Tree)
Liste
chaînée
(Linked List)
Hash Table
+
Linked List
Set
HashSet,
EnumSet
LinkedHashSet




NavigableSet
TreeSet

List
ArrayList,
Vector,
Stack
LinkedList
Queue
PriorityQueue



Deque
ArrayDeque
LinkedList
Map
HashMap,
IdentityHashMap
WeakHashMap
LinkedHashMap



NavigableMap
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
*
hors package
java.util.concurrent

8
JCF :
Les interfaces
Collection
*

Cours JAVA / Y.Laborde
Collection<E>
Set<E>
SortedSet
<E>
NavigableSet
<E>
List<E>
Queue<E>
Deque
<E>
Les interfaces
Collection

(core Collection interfaces)
(en italique : interfaces qui ne sont jamais
implémentées directement dans le JCF 6.0)
Interface
Commentaire
Accès
direct
Ordre maintenu
Doublons
admis
Élément
null admis
Collection<E>
Collection générale
- groupe d’objets
Non
/
/
/
Set<E>
Ensemble
- notion mathématique d’ensemble
Non
Non
Non
Oui (en g
al
)
SortedSet<E>
Ensemble ordonné
– ordre naturel ou à l’aide d’un
comparateur (interface Comparator)
Non
Oui
Non
Oui (en g
al
)
NavigableSet<E>
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<E>
Séquence
- collection ordonnée
Oui (en g
al
)
Oui
Oui (en g
al
)
Oui (en g
al
)
Queue<E>
File d’attente
– empilement/dépilement d’objets par
une des extrémités
Non
Oui: FIFO, LIFO,
autre
Oui
Non
Deque<E>
File d’attente à double sens
– op. aux 2 extrémités
Non
Oui: FIFO+LIFO
Oui
Non
conseillé
lire [
deck
]
*
hors package
java.util.concurrent

9
JCF :
Les classes
Collection
*

Cours JAVA / Y.Laborde
Les interfaces
Collection


(core Collection interfaces)
Collection<E>
Set<E>
SortedSet
<E>
NavigableSet
<E>
List<E>
Queue<E>
Deque
<E>
EnumSet

<E
extends

Enum
<E>>
HashSet
<E>
LinkHashSet
<E>
TreeSet
<E>
AbstractSet
<E>
ArrayList
<E>
Vector
<E>
Stack
<E>
AbstractList
<E>
AbstractSequentialList
<E>
LinkedList
<E>
RandomAccess

AbstractCollection
<E>
ArrayDeque
<E>
Les classes
Collection

(core Collection types)
Iterable
<T>
*
hors package
java.util.concurrent

implements
AbstractQueue
<E>
PriorityQueue
<E>
Pour
n’accepter
qu’un type
enum unique
(explicite ou
implicite)
10
JCF :
Les interfaces
Map
*

Cours JAVA / Y.Laborde
Les interfaces
Map

(core Map interfaces)
Interface
Commentaire
Accès
direct
Ordre
maintenu
Doublons admis
Élément
null admis
Map<K,V>
Dictionnaire
– objets (V) rangées à l’aide de clés (K)
Non
Non
Seulement sur V
Oui (K ou V)
SortedMap<K,V>
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<K,V>
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)
*
hors package
java.util.concurrent

Map
<K,V>
SortedMap
<K,V>
NavigableMap
<K,V>
Map
.
Entry
<K,V>
(en italique : interfaces qui ne sont jamais
implémentées directement dans le JCF 6.0)
L’interface Map.Entry<K,V>
(paire de clé/valeur ) :

La méthode
Map.entrySet()
renvoie une
collection-view
du
Map
(de type Set<Map.Entry<K,V>>), 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<K,V> ne sont valables que pour la durée de l'itération ; plus formellement, le
comportement d'une Map.Entry<K,V> 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.
public
static
interface
11
JCF :
Les classes
Map
*

Cours JAVA / Y.Laborde
Les interfaces
Map

(core Map interfaces)
Map
<K,V>
SortedMap
<K,V>
NavigableMap
<K,V>
Map.Entry
<K,V>
EnumMap

<K
extends

Enum
<K>,V>
HashMap
<K,V>
LinkHashMap
<K,V>
TreeMap
<K,V>
AbstractMap
<K,V>
Les classes
Map

(core Map types)
*
hors package
java.util.concurrent

implements
IdentityHashMap
<K,V>
WeakHashMap
<K,V>
AbstractMap.SimpleImmutableEntry
<K,V>
Hashtable
<K,V>
Properties

Dictionary
<K,V>
AbstractMap.SimpleEntry
<K,V>
public
static

public
static

public
static

12
JCF :
Détails
(1)

Cours JAVA / Y.Laborde
public interface Collection<E>
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 sous-
interfaces 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 sous-
interfaces)
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.
Voir
The Java Tutorials
:
http://java.sun.com/javase/6/docs/api/java/util/Collection.html
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.
13
JCF :
Détails
(2)

Cours JAVA / Y.Laborde
Voir
Tutorials & Code Camps (par MageLang Institute)
:
http://java.sun.com/developer/onlineTraining/collections/
Collection.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)
14
JCF :
Détails
(3)

Cours JAVA / Y.Laborde
Voir
Tutorials & Code Camps (par MageLang Institute)
:
http://java.sun.com/developer/onlineTraining/collections/
Collection.html#CollectionInterfacesAndClasses
Ces interfaces de files d’attente sont implémentées par les classes :
-


PriorityQueue
(: Queue)
-


ArrayDeque
et
LinkedList
(: Deque)
Les interfaces de Collection de
files d’attente
:
Queue et Deque
Ces interfaces de séquences sont implémentées
par les classes :
ArrayList
,

Vector
,
Stack
et
LinkedList
(: List)
Les interfaces de Collection de
séquences
:
List
15
JCF :
Détails
(4)

Cours JAVA / Y.Laborde
Voir
Tutorials & Code Camps (par MageLang Institute)
:
http://java.sun.com/developer/onlineTraining/collections/
Collection.html#CollectionInterfacesAndClasses
Ces interfaces de dictionnaires sont implémentées par les classes :
-


EnumMap
,
HashMap
,
IdentidyMap
,
WeakHashMap
et
LinkedHashMap
(: Map)
-


TreeMap
(: SortedMap)
Les interfaces de Collection de
dictionnaires
:
Map et SortedMap et Deque
Autres interfaces utiles

16
JCF :
Spécialiser une classe du JCF
(1)

Cours JAVA / Y.Laborde
Par exemple, comment disposer d’une liste de dominos qui permette de piocher ?

1) Par dérivation d’une classe du JCF

public class
DominoList



extends
ArrayList<Domino>
{

// Constructeurs


public
DominoList
( ) {



super ( );

}

public
DominoList
(Collection<Domino> c) {



super (c);

}

// Méthode pioche


public Domino
piocher
( ) {


if ( this.isEmpty ( ) ) return null;


int index = (int) (java.lang.Math.random ( ) * this.size ( ));


return this.remove (index);

}
}
Comment peut-on piocher un domino ?
Écrivez un code qui utilise la classe DominoList.
2) A l’aide d’une classe externe

public class
PiocheInList
{

// Méthode pioche


public
static
<E> E
piocher
( List<E> laPioche) {


if ( laPioche.isEmpty ( ) ) return null;


int index = (int) (java.lang.Math.random ( ) * this.size ( ));


return laPioche.remove (index);

}
}
Comment peut-on piocher un domino ?
Écrivez un code qui utilise la classe PiocheInList.
Piocher un domino
List<Domino> pioche =
new ArrayList<Domino> ( );
pioche.add ( new Domino(1,2) ); etc.
if ( ! Pioche.isEmpty ( ) ) {

Domino dominoPioché =
PiocheInList.piocher (pioche);


}
Piocher un domino
DominoList pioche =
new DominoList ( );
pioche.add ( new Domino(1,2) ); etc.
if ( ! Pioche.isEmpty ( ) ) {

Domino dominoPioché =
pioche.piocher ( ); …
}
* DominoList
est très spécialisée.
Elle ne permet de supporter et de ne
piocher que des dominos !
* De plus, si on regarde une DominoList
au travers de List<Domino>,
on ne peut
plus piocher !
* PiocheInList
est générique.
Elle permet de piocher toutes sortes
d’objets mis en liste et pas seulement des
dominos !
* La pioche est naturellement vue
comme une List<Domino> dans laquelle
on peut toujours piocher !
17
JCF :
Spécialiser une classe du JCF
(2)

Cours JAVA / Y.Laborde
3) Par encapsulation d’une classe du JCF

public class
DominoList
{

// Encapsulation d’une ArrayList


protected ArrayList<Domino> laListe;

// Constructeurs


public
DominoList
( ) {


this.laListe =
new ArrayList<Domino> ( );
}

public
DominoList
(Collection<Domino> c) {


this.laListe =
new ArrayList<Domino> (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<E> pour en
faire une List<Domino> !
* Mais, si on regarde une DominoList au
travers de List<Domino>,
on ne peut plus
piocher !
Chacune de ces 3
techniques a ses
avantages propres !
On pourra choisir
l’une ou l’autre.
18
JCF :
Les Wrappers
(1)

Cours JAVA / Y.Laborde
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 <T> List<T>
synchronizedList
(List<T> list)
)
,
o

rendre des collections non-modifiables

(read-only)

(ex:
public static <T> List<T>
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 <E> List<E>
checkedList
(List<E> list, Class<E> 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
.

Voir
The Java Tutorials
:
http://java.sun.com/docs/books/tutorial/collections/implementations/wrapper.html
19
JCF :
Wrappers

de synchronisation
(2)

Cours JAVA / Y.Laborde
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 <T> List<T>
synchronizedList
(List<T> 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<Type> listSync =
Collections.synchronizedList
( new ArrayList<Type>( ) );
ex2:

// DANGER - NOT OK car référence conservée sur la collection liée

List<Type> listInitiale = new ArrayList<Type>( );

// DANGER : même collection que listSync mais NON SYNCHRONISÉE

List<Type> listSync =
Collections.synchronizedList
( listInitiale );
_____________________________________________________________________________________



Synchroniser manuellement les
opérations d’itération
sur la collection
(comportement non déterministe sinon) :
ex1:

Collection<Type> c =
Collections.synchronizedCollection
(myCollection);

synchronized (c)
{ for (Type e : c) foo (e); }
ex2:

Map<KeyType, ValType>
mSync
= Collections.synchronizedMap ( new HashMap<KeyType, ValType>( ) );



Set<KeyType>
sKeys
=
mSync
.keySet();



synchronized (mSync)
{ while (KeyType k : sKeys) foo (k); }
// ATTENTION: synchroniser mSync et non sKeys !
Voir
The Java Tutorials
:
http://java.sun.com/docs/books/tutorial/collections/implementations/wrapper.html
20
JCF :
Wrappers

de non modif/checked
(3)

Cours JAVA / Y.Laborde
Rendre des collections NON MODIFIABLES
(les rendre tread-only)
:
Méthodes
statics
de la classe
Collections
:
public static <T> List<T>
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
.
Voir
The Java Tutorials
:
http://java.sun.com/docs/books/tutorial/collections/implementations/wrapper.html
Rendre des collections
TYPE-SAFE

(les rendre tread-only)
:
Méthodes
statics
de la classe
Collections
:
public static <T> List<T>
checkedList
(List<E> list, Class<E> 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<String> c = new HashSet<String>( );

// CODE DEBUG (code remplacé temporairement pour le debugging par :)

Collection<String> c =
Collections.checkedCollection
( new HashSet<String>( ),
String.class
);
21
Interop :
Compatibilité entre API Java
(1)

Cours JAVA / Y.Laborde
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

Collection

=>
Array

utiliser
dans l’interface Collection
:
Object
[]
toArray
()
ex1:

Collection
my_new_coll
= newMethod ( );


oldMethod (
my_new_coll.toArray ( )
);
ex2:

Collection
my_new_coll
= newMethod ( );


oldMethod ( (String[])
my_new_coll.toArray (new String[0])
);
________________________________________________________________

________________________________________________________________________________________
Pour

Collection

=>
Vector

utiliser
dans la classe Vector
:
public
Vector
(Collection<? extends E> c)
ex1:

Collection
my_new_coll
= newMethod ( );


oldMethod (
new Vector (my_new_coll)
);
________________________________________________________________

________________________________________________________________________________________
Pour

HashTable


utiliser
dans la classe Vector
:



public
Hashtable
(Map<? extends K,? extends
V
> t)
ex1:

Map
my_new_map
= newMethod ( );


oldMethod (
new Hashtable (my_new_map)
);
________________________________________________________________

________________________________________________________________________________________
Pour

Collection

=>
Enumeration

utiliser
dans la classe Collections :




public static <T> Enumeration<T>
enumeration
(Collection<T> c)

ex:

Collection
my_new_coll
=
newMethod
(arg);


oldMethod
(
Collections.enumeration (my_new_coll)
);
Voir
The Java Tutorials
:
http://java.sun.com/docs/books/tutorial/collections/interoperability/compatibility.html
22
Interop :
Compatibilité entre API Java
(2)

Cours JAVA / Y.Laborde
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

Array


=>
List
ou
Collection


utiliser
dans la classe Arrays
:
public static <T> List<T>
asList
(T... a)
ex:

Foo[]
my_old_array
= oldMethod (arg);


newMethod (
Arrays.asList (my_old_array)
);
________________________________________________________________

________________________________________________________________________________________
Pour

Vector



utiliser
tel quel
ex:

Vector
my_old_vector
= oldMethod (arg);


newMethod (
my_old_vector
);
________________________________________________________________

________________________________________________________________________________________
Pour

HashTable



utiliser
tel quel
ex:

Hashtable
my_old_hashtable
= oldMethod (arg);

newMethod (
my_old_hashtable
);
________________________________________________________________

________________________________________________________________________________________
Pour

Enumeration


=>
Collection


utiliser
dans la classe Collections :




public static <T> ArrayList<T>
list
(Enumeration<T> e)
ex:

Enumeration
my_old_enum
= oldMethod (arg);

newMethod (
Collections.list (my_old_enum)
);
Voir
The Java Tutorials
:
http://java.sun.com/docs/books/tutorial/collections/interoperability/compatibility.html
23
Interop :
Guide de bon usage du JCF

Cours JAVA / Y.Laborde
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

Voir
The Java Tutorials
:
http://java.sun.com/docs/books/tutorial/collections/interoperability/api-design.html
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 :
ex: retourner une interface List<T > ou une classe DominoList (qui fournit des méthodes utiles comme piocher un domino, …)



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
;