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
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...