Complements Java 5

Transcription

Complements Java 5
Chapitre 12
Le JDK 1.5
1
Quelques nouveautés:
–
Généricité
–
Nouvelle forme syntaxique pour for
–
Emballage/déballage pour les enveloppes de types primitifs
–
Méthodes avec un nombre variable d’arguments
–
Formatage des entrées(/sorties)
2
Généricité
Retour sur les classes de collections
Les classes de collections Java manipulent des objets du
type le plus général: Object
–
–
Avantage: souplesse
Inconvénients: viennent du fait que l'on est
souvent amené à manipuler des collections
d'objets d'un type spécifique.
Exemple: une liste d'étudiants
List l=new ArrayList();
Etudiant e=new Etudiant();
l.add(e);
...
for (Iterator it=l.iterator();it.hasNext();){
e=(Etudiant) it.next();
e.affiche();
}
Que se passe-t-il:
– si on oublie de caster ?
– si l contient autre chose que des étudiants ?
3
Solution (avant JDK 5.0)
Ecrire une classe spéciale pour chaque collection d'un
type donné.
Exemple (suite): pour Etudiant, on définit une classe
ListeEtudiant qui utilise un délégué de type List
class ListeEtudiant{
private List l;
…
public boolean ajouteEtudiant(Etudiant e){
…
}
…
// + implementation d'un mécanisme d'itération
}
Problème: on doit tout réecrire pour chaque nouveau
type.
 On aimerait pouvoir définir un « patron » de classe
avec un paramètre de type E que l’on pourrait instancier
par le type d’objets qui nous intéresse.
4
Généricité
(JDK 1.5)
Possibilité d'écrire du code utilisant des paramètres de
type.
Solution Java: proche des templates du C++
Exemple (suite):
Nouvelle classe de collection: ArrayList<E>
– classe/type générique.
– E: paramètre formel de type.
On peut ensuite instancier la classe avec le type qui
nous intéresse:
ArrayList<Etudiant>=new ArrayList<Etudiant>( );
Définit un type « liste d'objets de type Etudiant»
5
Avant:
List l=new ArrayList();
Etudiant e=new Etudiant();
l.add(e);
...
for (Iterator it=l.iterator();it.hasNext();){
e=(Etudiant) it.next();
e.affiche();
}
Avec les classes génériques:
List<Etudiant> l=new ArrayList<Etudiant>();
Etudiant e=new Etudiant();
l.add(e);
l.add(new Point()) //rejeté à la compilation!
...
for (Iterator<Etudiant> it =l.iterator<Etudiant>();
it.hasNext();){
(it.next()).affiche(); // casting inutile
}
Intérêt:
– factorisation du code
– moins de casting (code plus lisible et facile à
écrire)
– contrôle de type à la compilation
– moins de risques d'erreurs de casting à l'exécution
6
Les « nouvelles » classes de collections
 Interfaces et classes ont été remplacées par des
versions génériques
Exemple : l'interface Collection
Interface Collection<E>
public interface Collection<E>extends Iterable<E>
(l'interface Iterable contient une seule methode
iterator(); les classes qui implémentent cette interface
peuvent être utilisées avec la nouvelle boucle “for”)
(...)
7
Method Summary
boolean
add(E o)
Ensures that this collection contains the specified element (optional
operation).
boolean
addAll(Collection<? extends E> c)
Adds all of the elements in the specified collection to this collection
(optional operation).
void
clear()
Removes all of the elements from this collection (optional operation).
boolean
contains(Object o)
Returns true if this collection contains the specified element.
boolean
containsAll(Collection<?> c)
Returns true if this collection contains all of the elements in the specified
collection.
boolean
equals(Object o)
Compares the specified object with this collection for equality.
int
boolean
Iterator<E>
hashCode()
Returns the hash code value for this collection.
isEmpty()
Returns true if this collection contains no elements.
iterator()
Returns an iterator over the elements in this collection.
boolean
remove(Object o)
Removes a single instance of the specified element from this collection, if
it is present (optional operation).
boolean
removeAll(Collection<?> c)
Removes all this collection's elements that are also contained in the
specified collection (optional operation).
boolean
retainAll(Collection<?> c)
Retains only the elements in this collection that are contained in the
specified collection (optional operation).
int
Object[]
<T> T[]
size()
Returns the number of elements in this collection.
toArray()
Returns an array containing all of the elements in this collection.
toArray(T[] a)
Returns an array containing all of the elements in this collection; the
runtime type of the returned array is that of the specified array.
8
Nouvelle boucle « for »
 nouvelle syntaxe autorisée pour alléger l’écriture de
boucles
List l=new ArrayList( );
...
for (Iterator it=l.iterator();l.hasNext();)
(Etudiant)(it.next()).affiche();
...
Version java 1.5:
List<Etudiant> l=new ArrayList<Etudiant>( );
...
for (Etudiant e: l)
e.affiche();
...
Cette possibilité est offerte à toute classe (de collection)
qui implémente l'interface Iterable<T>
(méthode Iterator<T> iterator(); )
Cas des tableaux :
Si t est un tableau d'objets de type Etudiant
for (int i = 0; i < t.length; i++) {
t[i].affiche();
}
Version java 1.5:
for (Etudiant e: t) {
e.affiche();
}
9
Emballage et déballage pour les classes enveloppes
des types primitifs
Rappel : à chacun des types primitifs de Java (boolean,
byte, short, int, long, float, double, char) correspond une
classe enveloppe (Boolean, Byte, etc…). Chaque
instance d’une de ces classes enveloppe une unique
donnée membre du type associé.
Inconvénient : emballage et déballage (cf collections)
Exemple :
int valeur=5;
...
Integer obji=new Integer(valeur) ; // emballage
...
int n=obji.intValue(); // déballage
...
Nouveauté: emballage/déballage automatiques
On peut maintenant écrire :
int valeur=5 ;
…
Integer obji=valeur ;
…
int n=obji ;
…
10
Généricité et héritage
Attention:
- List<String> est un sous-type de
Collection<String>.
- Mais List<String> n’est pas un sous-type de
List<Object>
On ne peut pas ajouter n’importe quel objet à un
List<String>.
11
Wildcards (jokers)
Une méthode:
void afficheCollection(Collection c){
Iterator it=c.iterator();
while (it.hasNext())
System.out.println(it.next());
}
Comment réécrire cette méthode avec des collections
génériques ?
Premier essai:
void afficheCollection(Collection<Object> c){
Iterator it=c.iterator();
while (it.hasNext())
System.out.println(it.next());
}
Ne convient pas: on ne peut pas passer un objet de type
Collection<Etudiant> en paramètre.
On utilise un wildcard pour indiquer que le type du
paramètre est n'importe quelle instance de
Collection<T>:
void afficheCollection(Collection<?> c){
Iterator it=c.iterator();
while (it.hasNext())
System.out.println(it.next());
}
12
Remarque: seules les méthodes « sûres » pour tous les
types de paramètres peuvent être invoquées dans le
corps de la méthode:
void insereObjet(Collection<?> c){
c.add(new Object()); // rejeté à la compilation
}
Bounded Wildcards:
void manipCollection(Collection<? extends Etudiant > c){
...
}
Accepte tout paramètre de type Collection<T> où T
étend Etudiant.
Mêmes restrictions concernant les méthodes invoquées:
void insereObjet(Collection<? extends Etudiant> c){
c.add(new Etudiant()); // rejeté à la compilation
}
13
Classes génériques
Premier exemple : une classe générique pour manipuler
des paires d’éléments de type A.
class Paire<A>{
private A elem1,elem2 ;
public Paire(A elem1, A elem2 ){
this.elem1=elem1;
this.elem2=elem2;
}
public A getElem1(){
return elem1 ;
}
public A getElem2(){
return elem2;
}
public Paire<A> echange(){
return new Paire<A>(elem2,elem1);
}
}
...
Paire<String> p1=new Paire<String> (“premier”,”second”);
String s=p1.getElem1();
Paire<Integer> p2=new Paire<Integer> (123,456);
p2.echange();
Paire<Float> p3=p2;
// erreur
…
14
Deuxième exemple : une classe générique pour
manipuler des paires d’éléments dont le premier est de
type A et le second de type B.
class Paire<A,B>{
private A elem1,
private B elem2 ;
public Paire(A elem1, B elem2 ){
this.elem1=elem1;
this.elem2=elem2;
}
public A getElem1(){
return elem1 ;
}
public B getElem2(){
return elem2;
}
public Paire<B,A> echange(){
return new Paire<B,A>(elem2,elem1);
}
}
...
Paire<String, Integer> p1=new Paire<String,Integer> (“Alice”,123);
Paire<Integer,String> p2=p1.echange( );
...
Remarques :
- on peut imposer des contraintes aux paramètres de
type.
Exemple: class C<A, B extends List & Cloneable>{ ... }
15
Méthodes génériques
Exemple :
…
public static<T> void permute(T[] tab, int i,int j){
T temp=tab[i] ;
tab[i]=tab[j] ;
tab[j]=temp ;
}
...
String[] tabnoms;
Float[] tabflott;
...
C.permute(tabnoms,3,4); // inutile d'en dire plus
C.permute(tabflott,0,2);
...
.
16
Entrées formatées
La classe java.util.Scanner
« A simple text scanner which can parse primitive types
and strings using regular expressions »
Implémente Iterable<String>:
hasNext()
next()
(hasNextInt, hasNextDouble...)
(nextInt, nextDouble...)
Exemple:
Scanner s=new Scanner(System.in);
String c=s.next();
if (s.hasNextInt())
int v=s.nextInt();
s.close();
+ possibilité d'utiliser des délimiteurs et des expressions
régulières
17
Méthodes avec liste d’arguments variable
On peut appeler une même méthode avec un nombre
d’arguments qui peut varier d’un appel à l’autre (ce
n’est pas de la surcharge !).
Ces arguments doivent partager un type commun (une
superclasse commune), que l’on précise en le suivant de
« … » et d’un identificateur.
Exemple :
void afficherMessages(String pseudo, int id, String … messages){
System.out.println(« messages provenant de »+id) ;
for (int i=0 ; i<messages.length(); i++){
System.out.println(pseudo+”>”+messages[i]);
}
}
...
afficherMessages(‘’Alice123’’,123,”Bonjour”,”Au revoir”);
afficherMessages(‘’Bob’’,456, ‘’Bonjour’’,’’Y a quelqu’un ? ‘’,’’ok a+’’) ;
18

Documents pareils

Un petit mot sur les ArrayList

Un petit mot sur les ArrayList follow these steps: 1. Obtain an iterator to the start of the collection by calling the collection's iterator( ) 2. Set up a loop that makes a call to hasNext( ). Have the loop iterate as long as h...

Plus en détail