PDF Archive

Easily share your PDF documents with your contacts, on the Web and Social Networks.

Share a file Manage my documents Convert Recover PDF Search Help Contact



6 GénéricitéCollections .pdf


Original filename: 6-GénéricitéCollections.pdf
Title: Microsoft PowerPoint - 6-GénéricitéCollections VFIN.pptx
Author: Christine

This PDF 1.5 document has been generated by PScript5.dll Version 5.2.2 / Acrobat Distiller 9.5.5 (Windows), and has been sent on pdf-archive.com on 05/04/2017 at 14:44, from IP address 80.12.x.x. The current document download page has been viewed 149 times.
File size: 334 KB (20 pages).
Privacy: public file




Download original PDF file









Document preview


http://docs.oracle.com/javase/8/docs/api/

14

14-1

GÉNÉRICITÉ

GÉNÉRICITÉ

COLLECTIONS (CONTENEURS)

227

JAVA - © Christine Bonnet

COLLECTIONS ET PROGRAMMATION
GÉNÉRIQUE

228

JAVA - © Christine Bonnet

• Limitations
1. Impossible d'indiquer qu'une collection ne contient
qu'un seul type d'objet

 Code source unique utilisable avec des objets ou des
variables de types quelconques

2. Les éléments des collections sont déclarés de type
Object  transtypage obligatoire pour obtenir le
type voulu

• JDK 5  Interfaces, classes et méthodes génériques
surtout introduites pour sécuriser l'utilisation des
Collections (listes, ensembles…)

3. Certaines erreurs ne peuvent être repérées qu'à
l'exécution et pas à la compilation

• Avant le JDK 5
Généricité par le biais de l'héritage (toute classe dérive
au moins de la classe Object)

1

Exemple : une collection ArrayList peut comporter des
objets de type quelconque (Film, Livre, String,…). Appel
des méthodes de la classe sur ces différents types
d'objets

3

MAIS limitations et certains problèmes à l'exécution…
229

JAVA - © Christine Bonnet

ArrayList films = new ArrayList();
Film film1 = new Film("Les visiteurs","comédie");
films.add(film1);

Livre livre1 = new Livre(…);
films.add(livre1);
..
for (int i = 0; i < films.size();i++) {
System.out.println((Film)films.get(i).getTitre());
}

(ClassCastException)
230

2
JAVA - © Christine Bonnet

AVANTAGES DES "GENERICS'

• Pour éviter ces problèmes :
Écrire un code différent pour chaque collection d'un
type particulier

• Suppression du contrôle de type à l’exécution
 gain en sécurité, en temps de maintenance

 écrire plusieurs fois la même chose en
changeant le type !

• Pas de code supplémentaire à écrire (comme pour
les templates C++) pour introduire les generics

Utiliser les classes et méthodes génériques du JDK 5
Les generics permettent de s’abstraire du typage des
objets lors de la conception et donc de définir des
comportements communs quel que soit le type des
objets manipulés

231

JAVA - © Christine Bonnet

• Généralités

INTERFACES,CLASSES,
MÉTHODES GÉNÉRIQUES

 La manière de développer ne change donc
(pratiquement) pas

• Meilleure lisibilité, plus besoin de transtypage
• Possibilité de factoriser des comportements
232

CLASSE GÉNÉRIQUE
Exemple :

La généricité permet de paramétrer une classe, une interface,
une méthode ou un constructeur avec un ou plusieurs types
appelés "paramètres de type"

public class Couple<T> {
private T premier,second;
public Couple (T premier, T second) {
this.premier = premier;
this.second = second;
}
public void affiche() {
System.out.println("Premiere valeur : "+premier+"Deuxieme valeur :
"+second);
}
public T getPremier() {
return premier;
}
}

• Vocabulaire
List<E> : interface générique
ArrayList<E> : classe générique
E : paramètre de type (formel)
List<Film> f = new ArrayList<>();
ArrayList<> : classe (type) paramétrée
Film : argument de type concret
ArrayList : type non générique appelé "type raw" (brut)
233

JAVA - © Christine Bonnet

JAVA - © Christine Bonnet

Convention de nommage : le nom d'un paramètre de
type ne comporte qu'un caractère unique en majuscule
comme E (Elément) , T (Type), K (Key), N (Number),...
234

JAVA - © Christine Bonnet

• Utilisation de la classe générique
Déclaration d'un objet de type Couple : le type concret
correspondant à T doit être précisé. Ce type doit
obligatoirement être une classe

• Compilation du code générique
Pour assurer la compatibilité avec les anciennes
versions, en permettant de mêler code générique et
non générique
 mécanisme d'effacement ("type erasure ") :

Couple <String> cs; // cs couple d'objets de type String
Couple <Point> cp; // cp couple d'objets de type Point

le compilateur supprime toute information sur les
paramètres (et arguments) de type dans les
classes ou méthodes
Type "raw"

Appel du constructeur :

public class Boite<T> {
private T t;
public void ajout(T t) {
this.t = t;
}
public T get() {
return t;
}
}

cs = new Couple<> ("fou","reine");

Appel des méthodes :
cs.affiche();
String chaine = cs.getPremier();
Plus besoin de transtypage
235

JAVA - © Christine Bonnet

Effacement

Le compilateur produit le même byte code
236

Le compilateur :

public class Boite {
private Object t;
public void ajout(Object t)
{
this.t = t;
}
public Object get() {
return t;
}
}

JAVA - © Christine Bonnet

– Transtype si nécessaire
Boite<Integer> boiteEntier;

Integer unEntier = boiteEntier.get();
 Integer unEntier = (Integer) boiteEntier.get();

– Remplace les types paramétrés par les types "raw"
correspondants :
class Boite<T>  class Boite

/* le compilateur connaît le type de boiteEntier grâce à sa
déclaration */

List <Employe> employes = new ArrayList<>();
 List employes = new ArrayList();
Boite<String> bs = new Boite<> (…..);
Boite<Double> bd = new Boite<> (…..);
 bs et bd appartiennent après compilation, pour la machine
virtuelle, à la même classe : le type brut "Boite"

– Vérifie le typage compte tenu de toutes les
informations (paramètres de type compris)
Double d = boiteEntier.get();  rejeté
// car traduit en Double d = (Integer)boiteEntier.get()

T transformé en Object
private T t;  private Object t;

Solution : les jokers (wildcards) <?> (? : type
fixé mais inconnu)
237

JAVA - © Christine Bonnet

238

JAVA - © Christine Bonnet

EFFACEMENT  RESTRICTIONS POUR
LES CLASSES GÉNÉRIQUES

• instanceof

• Impossibilité d'instancier un objet d'un type générique
public class Boite<T> {

public class MaClasse<E> {
public static void uneMethode(Object item) {

L'appel à new T() est rejeté par le
compilateur

private T x; // OK

Au moment de l'exécution le type
T aura disparu (devenu Object)

public void f(…) {
x = new T(); // INTERDIT

if (item instanceof E) { // INTERDIT

• Transtypage

 la JVM ne peut donc pas
connaître le type exact de l'objet
à instancier

}
}

• Même problème pour des tableaux

E obj = (E)new Object(); // Unchecked cast warning

• Un champs statique ne peut pas être d'un type paramétré

public class Boite<T> {

class Boite<T>

private T[] tab; // OK

{ static T dimension; // INTERDIT

public void f(…) {
tab = new T[100]; // INTERDIT
}}
1-239

JAVA - © Christine Bonnet

240

JAVA - © Christine Bonnet

MÉTHODE ET CONSTRUCTEUR
GÉNÉRIQUES

• Exceptions : impossibilité de créer une classe

générique dérivée de Throwable, donc a fortiori de
Exception ou Error
public class ExceptionBoite<T> extends Exception // erreur de compilation

Des paramètres de type peuvent être déclarés dans

• Exceptions : impossibilité de lever une exception

les signatures de méthodes et constructeurs pour

(throw) à l'aide d'un objet d'une classe générique ou
d'intercepter une exception (catch) en se basant sur
un objet d'une classe générique

241

JAVA - © Christine Bonnet

créer des méthodes et constructeurs génériques

242

JAVA - © Christine Bonnet

Exemple :

• Inférence de type

public class Boite<T> {
private T t;
public void ajout(T t) {
this.t = t;
}
public T get() {
return t;
}
public <U> void controle(U u){
System.out.println("T: " + t.getClass().getName());
System.out.println("U: " + u.getClass().getName());
}
public static void main(String[] args) {
Boite<Integer> boiteEntiers = new Boite<>();
boiteEntiers.ajout(10);
boiteEntiers.controle("un texte");
}
}

243

Résultat :
T: java.lang.Integer
U: java.lang.String

JAVA - © Christine Bonnet

public static <U> void remplirBoites(U u, List<Boite<U>> boites) {
for (Boite<U> boite : boites) {
boite.ajout(u);
}
}
// Utilisation de cette méthode
Crayon crayonRouge =new Crayon();
Boite<Crayon> boiteCrayons1 = new Boite<>();
List<Boite<Crayon>> listeBoitesCrayons = new ArrayList<>();
listeBoitesCrayons.add(boiteCrayons1);
// Syntaxe complète pour invoquer cette méthode en fournissant
// explicitement le type correspondant à U. Vérification à la compilation
Boite.<Crayon>remplirBoites(crayonRouge, listeBoitesCrayons);
// Invocation avec un type inconnu  inférence de type
// le compilateur infère que U est Crayon
Boite.remplirBoites(crayonRouge, listeBoitesCrayons);

L'inférence de type permet d'invoquer une méthode
générique comme une méthode "ordinaire" sans
spécifier de type entre "< >"
244

JAVA - © Christine Bonnet

• Effacement et méthodes génériques

• Inférence de type (suite)
public static <T> T choix(T a, T b) { …
}
// Utilisation de cette méthode
Number n = choix(new Integer(0), new Double(0.0));

Le compilateur infère Number qui est la "plus proche"
super classe de Integer et Double

public static <T> T hasard (T [] tabValeurs) {
// choix au hasard d'une position dans le tableau de valeurs
int n = tabValeurs.length;
if (n==0) return null;
int i = (int) (n*Math.random());
// public static double random () : renvoie un nombre entre 0.0 et 1.0
return tabValeurs[i];
}
// Utilisation de cette méthode
Integer [] tabEntiers = {1, 2, 5, 8, 4};
Integer n = hasard (tabEntiers);
String [] tabChaines = {"bonjour", "hello", "hi"};
String s = hasard (tabChaines);

Effacement
public static Object hasard (Object [] valeurs) { …

Integer n = (Integer) hasard (tabi); // insertion d'un cast par le compilateur
String s = (String) hasard (tabs);
245

JAVA - © Christine Bonnet

246

JAVA - © Christine Bonnet

LES COLLECTIONS

14.2

• Objet qui regroupe de multiples éléments dans une
seule entité

• Utilisation de collections pour

COLLECTIONS

– stocker, retrouver, manipuler des données
– transmettre des données d’une méthode à une autre

• Exemples :
un dossier de courrier : collection de mails
un répertoire téléphonique : collection d'associations
noms-numéros de téléphone

247

JAVA - © Christine Bonnet

LES COLLECTIONS DANS JAVA
• La version 2 de Java a élargi et harmonisé la bibliothèque
de classes utilitaires par l'introduction d'un "framework"
pour la gestion des collections (package java.util)
Architecture unifiée pour représenter et manipuler les
collections composée de trois parties :
– Interfaces : types de données abstraits représentant
les collections
– Implémentations de ces interfaces
– Algorithmes : méthodes réalisant des opérations
utiles sur les collections : tri, recherche,…
Similaire à STL (Standard Template Library) en C++
Framework : ensemble de bibliothèques, d'outils et de conventions (guide
architectural) permettant le développement d'applications
249

JAVA - © Christine Bonnet

248

JAVA - © Christine Bonnet

• Depuis le JDK 5.0
– On peut indiquer le type des objets contenus dans
une collection grâce à la généricité
 le recours au cast n'est plus nécessaire
– Toutes les collections peuvent être utilisées de
manière générique
– Vérification du typage à la compilation
– Introduction d'une nouvelle interface Queue
destinée à la gestion des files d'attentes
– Nouvelle boucle for-each spécialement conçu
pour itérer sur les collections

250

JAVA - © Christine Bonnet

LES INTERFACES

LES IMPLEMENTATIONS DE COLLECTION

Deux hiérarchies principales
– Collection<E> (Collection)

Interfaces des collections usuelles : Vector<E> (obsolète),
ArrayList<E>, LinkedList<E>, HashSet<E>, TreeSet<E>, …
– Tables associatives Map<K,V> (Map)
Collections indexées par des clés (on associe à un objet
de la collection une clé) : HashTable<K,V>,
HashMap<K,V>, TreeMap<K,V>, …
251

Ces implémentations se situent dans une hiérarchie de classes abstraites

JAVA - © Christine Bonnet

252

LES IMPLEMENTATIONS DE MAP

JAVA - © Christine Bonnet

COLLECTIONS ET TYPES PRIMITIFS
• Les collections ne peuvent pas contenir des valeurs des
types primitifs (int, float, double, char,…)

• Avant le JDK 5.0, il fallait donc utiliser explicitement les
classes "enveloppes" (Wrapper class) des types
primitifs, Integer par exemple
Wrapper class
Pour permettre l’utilisation de valeurs des types de
base en tant qu’objet on "encapsule » la valeur dans
un objet à l’aide d’une classe "enveloppe"
Pour chacun des types de base il existe une classe
enveloppe dont le nom correspond au nom du type
de base avec une Majuscule

253

JAVA - © Christine Bonnet

254

JAVA - © Christine Bonnet

Wrapper class (suite)

• A partir du JDK 5.0, les conversions entre les types
Méthodes statiques pour
conversions de chaînes
Classe

Constructeur

Accès à la valeur

vers les valeurs du type de

VOIR l'AUTO BOXING

base

Integer(int value)

int intValue()

Integer valueOf(String s)

Integer intObj =

int i =

int parseInt(String s)

new Integer(45);

intObj.intValue();

Integer intObj =

Double(double
value)

double doubleValue()

Double valueOf(String s)

Boolean(boolean
value)

boolean booleanValue()

"enveloppe"
Integer

primitifs et les classes enveloppes peuvent être
implicites grâce à l'auto boxing (/ unboxing)
AUTO BOXING

Possibilité de passer automatiquement d’un type
simple (boolean, byte, char, short, int, long, float,
double) vers le type objet (classe Wrapper")
correspondant (Boolean, Byte, Char, Short,Integer,
Long, …)

Integer.valueOf("45");
Double

Boolean

double parseDouble(String s)

AUTO UNBOXING

Boolean valueOf(String s)

Gère la transformation inverse



255

JAVA - © Christine Bonnet

256

AUTOBOXING / UNBOXING (suite)
JDK 5.0

// Avant JDK 5.0

Integer entier = 0;

// Integer entier = new Integer(0);

int j = entier;

// int j = entier.intValue();

COLLECTIONS - CONCEPTS GÉNÉRAUX
• Égalité d'éléments d'une collection  méthode equals
– Pour des éléments de type String, File ou d'une
classe enveloppe (Wrapper class)

List ld = new ArrayList();

 leur méthode equals se base réellement sur la
valeur des objets

List<Double> ld2 = new ArrayList<>();
// Auto boxing
ld.add (3.14);

// ld.add (new Double(3.14));

ld2.add(3.14);

– Pour les autres

// Boxing par transtypage
Double d = (Double)3.14;

 comparaison avec la méthode equals héritée
de Object : égalité de références

// Double d = new Double(3.14);

// Unboxing
double d1= (Double) ld.get(i); // double d1 = ((Double) ld.get(i)).doubleValue();
// Auto Unboxing
double d2= ld2.get(i);
257

JAVA - © Christine Bonnet

// double d2 = ((Double) ld.get(i)).doubleValue();
JAVA - © Christine Bonnet

 Redéfinition de equals
Exception pour TreeSet qui utilise compareTo ou un éventuel
comparateur

258

JAVA - © Christine Bonnet

• Ordre des éléments dans une collection

Interface Comparable<T>
– Certaines classes comme String, File ou les classes
enveloppes (Wrapper class) implémentent l'interface
Comparable<T>  méthode compareTo

– Ordre
- Ensembles : aucun

(par exemple String implémente Comparable<String>)

- Listes chaînées, vecteurs dynamiques : ordre
d'insertion des éléments

– Implémentation de la méthode compareTo pour des
objets d'une classe :
public int compareTo (T objet2)

– Ordonner les éléments d'une collection (pour tri,
recherche du minimum, du maximum, …)

Compare l'objet courant (this) à l'objet objet2

Utilisation de :
- l'interface Comparable<T>, méthode compareTo

Renvoie un entier :
– négatif si this est plus petit que objet2
– positif si this est plus grand que objet2
– 0 si les 2 objets ont la même valeur

- ou d'un objet comparateur (d'une classe
implementant l'interface Comparator<T>),
méthode compare
259

JAVA - © Christine Bonnet

Interface Comparator<T>
Utilisation : construction d'un objet comparateur si
– les éléments appartiennent à une classe qui
n'implémente pas l'interface Comparable<T>

260

JAVA - © Christine Bonnet

Exemple :
public class CompareSalaire implements Comparator<Employe> {
public int compare(Employe e1, Employe e2) {

– on ne veut pas trier suivant l'ordre donné par
Comparable (ou plusieurs ordres différents sur une
même collection)

double s1 = e1.getSalaire();
double s2 = e2.getSalaire();
if (s1 > s2)
return +1;

Implémentation de la (seule) méthode :
int compare(T o1, T o2)

else if (s1 < s2)
return –1;

renvoie

else

- un entier positif si o1 est "plus grand" que o2
- 0 si o1 a la même valeur (au sens de equals) que o2

}

return 0;
}

- un entier négatif si o1 est "plus petit" que o2
261

JAVA - © Christine Bonnet

262

JAVA - © Christine Bonnet


Related documents


2 basesjavadebut
4 progobjjava
6 genericitecollections
1 introjava
5 progobjjavasuite
pract


Related keywords