Java Avancée
Chapitre II : Généricité
Contenu
Principes généraux
Types génériques imbriqués
Types paramètres bornés
Méthodes génériques
Classes d’usage courant
121 Java Avancée- Selma BATTI ATTIA 2020/2021
Principes
Paramétrer une classe ou une méthode par un type:
une pile de X
En java toute classe étant dérivée de Object, cela permet
d'obtenir une forme de généricité sans contrôle des
types
une pile d'Object
La généricité en Java est un mécanisme "statique" assez
complexe
la généricité existe dans d'autres langages (exemple C++
et Ada) (mais de façon différente)
122 Java Avancée- Selma BATTI ATTIA 2020/2021
Exemple: File
public class Cellule<E>{
private Cellule<E> suivant;
private E element;
public Cellule(E val) {
[Link]=val;
}
public Cellule(E val, Cellule suivant){
[Link]=val; [Link]=suivant;
}
public E getElement(){ return element;}
public void setElement(E v){
element=v;
}
public Cellule<E> getSuivant(){ return suivant;}
public void setSuivant(Cellule<E> s){
[Link]=s;
}
}
123 Java Avancée- Selma BATTI ATTIA 2020/2021
Suite
class File<E>{
protected Cellule<E> tete;
protected Cellule<E> queue;
private int taille=0;
public boolean estVide(){
return taille==0;
}
public void enfiler(E item){
Cellule<E> c=new Cellule<E>(item);
if (estVide())
tete=queue=c;
else{
[Link](c);
queue=c;
}
taille++;
} //..
124 Java Avancée- Selma BATTI ATTIA 2020/2021
suite
public E defiler(){
if (estVide())
return null;
Cellule<E> tmp=tete;
tete=[Link]();
taille--;
return [Link]();
}
public int getTaille(){
return taille;
}
}
125 Java Avancée- Selma BATTI ATTIA 2020/2021
Usage
Cellule<Integer> cel=new Cellule<Integer>(23);
File<Integer> fi=new File<Integer>();
File<String> fs=new File<String>();
File<Object> fobj=new File<Object>();
String[] st={"zéro","un","deux",
"trois","quatre","cinq"};
for(int i=0;i<[Link];i++){
[Link](st[i]);
[Link](i);
}
126 Java Avancée- Selma BATTI ATTIA 2020/2021
Remarques
Une déclaration de type générique peut avoir plusieurs
paramètres:
Map<K,V>
Contrôle de type
[Link](4) est refusé à la compilation
127 Java Avancée- Selma BATTI ATTIA 2020/2021
Types génériques, pourquoi?
Vérification de type:
List myIntList = new LinkedList();
[Link](new Integer(0));
Integer x = (Integer) [Link]().next();
Et:
List<Integer> myIntList = new LinkedList<Integer>();
[Link](new Integer(0));
Integer x = [Link]().next();
128 Java Avancée- Selma BATTI ATTIA 2020/2021
Invocation et type en paramètre
public interface List <E>{
void add(E x);
Iterator<E> iterator();
}
public interface Iterator<E>{ E next(); boolean hasNext();}
List<Integer> pourrait correspondre à (comme en C++):
public interface IntegerList {
void add(Integer x);
Iterator<Integer> iterator();
}
Mais… une déclaration d'un type générique crée un vrai type (qui est compilé comme un
tout) et il n'y a pas de type pour List<Integer>
129 Java Avancée- Selma BATTI ATTIA 2020/2021
Typage
Une invocation ne crée pas un nouveau type:
([Link]()==[Link]()) est vrai
la classe est ici File
il s'agit surtout d'un contrôle (effectué à la compilation)
à l'exécution fi n'a plus aucune information sur quelle
invocation a permis sa construction
130 Java Avancée- Selma BATTI ATTIA 2020/2021
Conséquences
Aucune instanciation n'est possible pour un type
argument
Dans l'exemple:
E v=new E();
est impossible,
Pas de tableau de E
131 Java Avancée- Selma BATTI ATTIA 2020/2021
Exemple
public E[] toArray(File<E> f){
E[] tab = new E[[Link]()]; //erreur
for(int i=0; i<[Link](); i++)
tab[i]=[Link]();
}
Comment construire un tableau sans connaître le type de base?
La classe Array et la méthode [Link]()
permettraient de résoudre ce problème (mais sans contrôle de
type)
On peut aussi utiliser la classe Object.
132 Java Avancée- Selma BATTI ATTIA 2020/2021
Object
public static <E> Object[] toArray(File<E> f){
Object[] tab=new Object[[Link]()];
for(int i=0;i<[Link]();i++)
tab[i]=[Link]();
return tab;
}
mais on perd l'avantage du contrôle de type.
133 Java Avancée- Selma BATTI ATTIA 2020/2021
Contrôle du type
Pourtant, on peut passer un objet d'un type avec
paramètre à une méthode.
Comment se fait le passage des paramètres?
le compilateur passe le type le plus général
(Object) et utilise le cast pour assurer le
contrôle du typage.
134 Java Avancée- Selma BATTI ATTIA 2020/2021
Types génériques imbriqués
public class FileSimpleChainageb <E>{
public class Cellule{
private Cellule suivant;
private E element;
public Cellule(E val) {
[Link]=val;
}
public Cellule(E val, Cellule suivant){
[Link]=val;
[Link]=suivant;
}
public E getElement(){
return element;
}
public void setElement(E v){
element=v;
}//...
135 Java Avancée- Selma BATTI ATTIA 2020/2021
Suite
public Cellule getSuivant(){
return suivant;
}
public void setSuivant(Cellule s){
[Link]=s;
}
}
protected Cellule tete;
protected Cellule queue;
private int taille=0;
public boolean estVide(){
return taille==0;
}
public int getTaille(){
return taille;
}
136 Java Avancée- Selma BATTI ATTIA 2020/2021
Fin…
public void enfiler(E item){
Cellule c=new Cellule(item);
if (estVide())
tete=queue=c;
else{
[Link](c);
queue=c;
}
taille++;
}
public E defiler(){
if (estVide())
return null;
Cellule tmp=tete;
tete=[Link]();
taille--;
return [Link]();
}
137 Java Avancée- Selma BATTI ATTIA 2020/2021
Sous-typage
List<String> ls = new ArrayList<String>();
List<Object> lo = ls; //1
[Link](new Object()); //2
String s = [Link](0); //3 !
Si A est une extension de B, F<A> n'est pas une extension de F<B>:
//1 est interdit
Pour les tableaux:
si A est une extension de B un tableau de A est une extension de tableau de B.
//1 est autorisé, mais ensuite //2 est interdit
138 Java Avancée- Selma BATTI ATTIA 2020/2021
Joker '?'
void printCollection(Collection<Object> c) {
for (Object e : c) { [Link](e);}
}
Ne fonctionne pas avec une Collection<Integer>
Une collection de n'importe quoi ('?')
void printCollection(Collection<?> c) {
for (Object e : c){ [Link](e);}
}
est possible (n'importe quoi est un objet).
Mais
Collection<?> c = new ArrayList<String>();
[Link](new Object()); // erreur compilation
139 Java Avancée- Selma BATTI ATTIA 2020/2021
Classe "Vector"
Un vecteur est un tableau dynamique dont les éléments
sont des références d'objets.
C'est un tableau d'objets dont la taille peut varier au fil
du temps ce qui n'est pas possible avec les tableaux
statiques.
140 Java Avancée- Selma BATTI ATTIA 2020/2021
Quelques méthodes de "Vector"
Méthodes Description
public Vector() construit un vecteur vide
public final boolean isEmpty() rend vrai si le vecteur est vide
public final int size() nombre d'élément du vecteur
public final void addElement(Object obj) ajoute l'objet obj au vecteur
public final Object elementAt(int index) référence de l'objet n° index du vecteur - les
indices commencent à 0
public final Enumeration elements() l'ensemble des éléments du vecteur sous forme
d'énumération
public final Object firstElement() référence du premier élément du vecteur
public final Object lastElement() référence du dernier élément du vecteur
141 Java Avancée- Selma BATTI ATTIA 2020/2021
Classe "ArrayList"
La classe "ArrayList" est analogue à la classe "Vector".
Elle n'en diffère essentiellement que lorsque elle est
utilisée simultanément par plusieurs threads d'exécution.
Les méthodes de synchronisation des threads pour
l'accès à un "Vector" ou un "ArrayList" diffèrent.
Endehors de ce cas, on peut utiliser indifféremment l'un
ou l'autre.
142 Java Avancée- Selma BATTI ATTIA 2020/2021
Méthodes de "ArrayList"
Méthodes Description
ArrayList() construit un tableau vide
int size() nombre d'élément du tableau
void add(Object obj) ajoute l'objet référencé par obj au tableau
void add(int index,Object obj) ajoute l'objet référencé par obj au tableau en position index
Object get(int index) référence de l'objet n° index du tableau - les indices
commencent à 0
boolean isEmpty() rend vrai si le tableau est vide
void remove(int index) enlève l'élément d'indice index
void clear() vide le tableau de tous ses éléments
Object[] toArray() met le tableau dynamique dans un tableau classique
String toString() rend une chaîne d'identification du tableau
143 Java Avancée- Selma BATTI ATTIA 2020/2021
Classe "Arrays"
La classe "[Link]" donne accès à des méthodes
statiques permettant différentes opérations sur les
tableaux en particulier les tris et les recherches
d'éléments.
144 Java Avancée- Selma BATTI ATTIA 2020/2021
Méthodes de "Arrays"
Méthodes Description
static void sort(tableau) trie tableau en utilisant pour cela l'ordre
implicite du type de données du tableau, nombre
ou chaînes de caractères.
static void sort (Object[] tableau, Comparator trie tableau en utilisant pour comparer les
C) éléments la fonction de comparaison C
static int binarySearch(tableau,élément) rend la position de élément dans tableau ou une
valeur <0 sinon. Le tableau doit être auparavant
trié.
static int binarySearch(Object[] tableau,Object idem mais utilise la fonction de comparaison C
élément, Comparator C) pour comparer deux éléments du tableau.
145 Java Avancée- Selma BATTI ATTIA 2020/2021
Classe "Enumeration"
"Enumeration" est une interface et non une classe.
Ses méthodes sont :
public abstract boolean hasMoreElements() : rend vrai si
l'énumération a encore des éléments
public abstract Object nextElement() : rend la référence de
l'élément suivant de l'énumération
146 Java Avancée- Selma BATTI ATTIA 2020/2021
Méthodes de "Enumeration"
Méthodes Description
public abstract boolean rend vrai si l'énumération a encore des éléments
hasMoreElements()
public abstract Object rend la référence de l'élément suivant de
nextElement() l'énumération
147 Java Avancée- Selma BATTI ATTIA 2020/2021
Classe "Hashtable"
La classe "Hashtable" permet d'implémenter un
dictionnaire. On peut voir un dictionnaire comme un
tableau à deux colonnes : clé valeur
Les clés sont uniques, c.a.d. qu'il ne peut y avoir deux
clés identiques.
148 Java Avancée- Selma BATTI ATTIA 2020/2021
Quelques méthodes de "Hashtable"
Méthodes Description
public Hashtable() constructeur - construit un dictionnaire vide
public int size() nombre d'éléments dans le dictionnaire - un
élément étant une paire (clé, valeur)
public Object put(Object k, Object v) ajoute la paire (k, v) au dictionnaire
public Object get(Object key) récupère l'objet associé à la clé key ou null si la
clé key n'existe pas
public boolean containsKey(Object key) vrai si la clé key existe dans le dictionnaire
public boolean contains(Object value) vrai si la valeur value existe dans le dictionnaire
public Enumeration keys() rend les clés du dictionnaire sous forme
d'énumération
public Object remove(Object key) enlève la paire (clé, valeur) où clé=key
public String toString() identifie le dictionnaire
149 Java Avancée- Selma BATTI ATTIA 2020/2021