Programmation Par Objets collections package java.util © B. Carré Polytech’Lille 1 Utilitaires et collections de Java 2 Le package java.util a été refondu en Java 2: introduction d’une classe Arrays fournissant des utilitaires tels que égalité, tri et recherche dans les tableaux (sous la forme de méthodes statiques). des interfaces de comparaison d’objets permettant des opérations génériques de tri et de recherche. introduction de nouvelles SD (ou révision d’anciennes): List : distinction liste chainée (LinkedList)/liste contigüe (ArrayList) Set : ensembles Map : tables d’association © B. Carré Polytech’Lille 2 Egalité de tableaux égalité de contenu boolean Arrays.equals(t1,t2) <=> (t1.length == t2.length) & (t1[i].equals(t2[i]),∀i<t1.length) cette méthode est surchargée pour les types de base la méthode equals de Object teste par défaut l’égalité physique (même instance au sens de ==). il est possible de la redéfinir pour tester l’égalité logique d’objets. Exemple : égalité de contenu entre chaînes définie dans String © B. Carré Polytech’Lille 3 Egalité de tableaux : exemple public class Ouvrage { public boolean equals(Object o) { return ( (o instanceof Ouvrage) && (auteur.equals(((Ouvrage)o).getAuteur())) && (titre.equals(((Ouvrage)o).getTitre())) ); } ...} //le test de type peut se faire par // traitement de l’exception ClassCastException public class Ouvrage { public boolean equals(Object o) { try { Ouvrage lautre = (Ouvrage)o; return ((auteur.equals(lautre.getAuteur())) && (titre.equals(lautre.getTitre()))); } catch (ClassCastException ex) {return false;} }...} © B. Carré Polytech’Lille 4 Egalité de tableaux : exemple Ouvrage t1[] = { new Ouvrage("Germinal","Zola"), new Ouvrage("C","Kernighan”), new Ouvrage(“Java”,”Eckel”) }; Ouvrage t2[] = { new Ouvrage(“Germinal”,”Zola”), new Ouvrage(“C”,”Kernighan”), new Ouvrage(“Java”,”Eckel”) }; t1==t2 est false <=> t1.equals(t2) (égalité physique par défaut) tout comme : t1[i]==t2[i] Arrays.equals(t1,t2) est true (égalité logique) tout comme t1[i].equals(t2[i]) (égalité logique itérée sur les éléments) © B. Carré Polytech’Lille 5 Tri void Arrays.sort(t) Les éléments du tableau doivent implanter la méthode compareTo spécifiée par l’interface Comparable: public interface Comparable { public int compareTo(Object obj); // < 0 si this < obj // = 0 si this = obj // > 0 si this > obj } © B. Carré Polytech’Lille 6 Tri : exemple // sachant : class String implements Comparable // ordre sur les ouvrages <=> ordre sur leur auteur : public class Ouvrage implements Comparable { public int compareTo(Object obj) { return auteur.compareTo(((Ouvrage)obj).getAuteur()); }...} //application Arrays.sort(t1); // resultat Java Eckel C Kernighan Germinal Zola © B. Carré Polytech’Lille 7 Ordres multiples La technique du compareTo par l’interface Comparable est dite «de l’ordre naturel» (méthode de l’objet). Elle pose problème si: on veut trier des objets dont la classe n’implémente pas Comparable ou si l’ordre implémenté ne convient pas ou encore si l’on désire ordonner les objets selon plusieurs critères. Une autre technique est offerte sous la forme de «callbacks» au travers «d’objets comparateurs» qui doivent implémenter l’interface Comparator : public interface Comparator { public int compare(Object o1, Object o2); // < 0 si o1 < o2 // = 0 si o1 = o2 // > 0 si o1 > o2 } © B. Carré Polytech’Lille 8 Ordres multiples Le tri de tableaux s’effectue alors en fournissant l’objet comparateur en paramètre : Arrays.sort(Object t[], Comparator c) Exemple // nouvel ordre des ouvrages sur leur titre : public class ComparateurDeTitres implements Comparator{ public int compare(Object o1, Object o2) { return((Ouvrage)o1).getTitre() .compareTo(((Ouvrage)o2).getTitre()); }} //application Arrays.sort(t2, new ComparateurDeTitres()); © B. Carré Polytech’Lille 9 Recherches ordonnées recherche d’un objet dans un tableau ordonné par ordre naturel int Arrays.binarySearch(Object t[], Object obj) recherche d’un objet dans un tableau ordonné par comparateur int Arrays.binarySearch(Object t[], Object obj, Comparator c) Ces méthodes renvoient : l’indice de l’élément s’il est trouvé (- <indice d’insertion> - 1) sinon, avec: <indice d’insertion> = 0 si obj < t[0], t.length si obj > t[t.length-1] t[<indice d’insertion> - 1] < obj < t[<indice d’insertion>], sinon La recherche ordonnée sur un tableau non trié est imprédictible! Arrays.binarySearch(t1,new Ouvrage(“Germinal”,”Zola”))=2 Arrays.binarySearch(t1,new Ouvrage(“Parapente”,”AliGali”))=-1 Arrays.binarySearch(t1,new Ouvrage(“IA”,”Nilsson”))=-3 Arrays.binarySearch(t2,new Ouvrage(“Germinal”,”Zola”), new ComparateurDeTitres()))=1 © B. Carré Polytech’Lille 10 java.util de Java 2 Collection List ArrayList Set LinkedList HashSet TreeSet Map interfaces TreeMap HashMap © B. Carré Polytech’Lille classes 11 Collection Les collections sont des regroupements d’objets sous la forme de listes (duplications possibles) ou d’ensembles (sans duplications). L’interface Collection est commune mais implémentée de façon différente selon la classe. Principales fonctionnalités public interface Collection public boolean add(Object o) public void clear() public boolean contains(Object o) //par equals() public boolean equals(Object o) public boolean isEmpty() public boolean remove(Object o) public int size() public Object[] toArray() //inverse deArrays.asList(t) public Iterator iterator() © B. Carré Polytech’Lille 12 Collection Il existe des versions itérées de add, contains, remove suffixées par All et paramétrées par une collection (quelconque) d’objets, par exemple: public boolean addAll(Collection c); public boolean containsAll(Collection c); <=> c inclus dans this Itérateur public interface Iterator public boolean hasNext() public Object next() throws NoSuchElementException Exemple public class Circuit { private Collection composants = new LinkedList(); public void addPorte(Porte p) {composants.add(p);} public void afficher() { Iterator iter = composants.iterator(); while (iter.hasNext()) ((Porte)iter.next()).display(); }...} © B. Carré Polytech’Lille 13 Les listes : java.util.List Deux sortes : liste chainée: LinkedList liste contigüe: ArrayList (nouvelle version de la classe Vector) issues d’une même interface: public interface List extends Collection qui permet un contrôle externe complet et indicé (à partir de 0) sur l’ordre des éléments : public void add(int index, Object element) // sachant: add ajoute en queue public Object get(int index) throws IndexOutOfBoundsException public Object set(int index, Object element) throws IndexOutOfBoundsException public Object remove(int index) throws IndexOutOfBoundsException public int indexOf(Object o) // indice de la 1ere occurence -1 si !this.contains(o) © B. Carré Polytech’Lille 14 LinkedList / ArrayList Performances ArrayList est plus performante sur les accès aléatoires (get(i), set(i, elt),...) LinkedList est plus performante sur les opérations d’ajout/retrait (add, remove, ...) Fonctionnalités La classe LinkedList augmente le protocole de List avec des opérations de manipulation en tête et queue qui en fait la meilleure candidate pour implanter des LIFO et des FIFO. public class LinkedList public void addFirst(Object o), addLast(Object o) public Object getFirst(), getLast() throws NoSuchElementException public Object removeFirst(), removeLast() throws NoSuchElementException © B. Carré Polytech’Lille 15 Itérateur de listes En plus de l’Iterator de Collection, List ajoute : public interface ListIterator extends Iterator public boolean hasPrevious() // ordre inverse public Object previous() public int nextIndex() // itération sur les indices public int previousIndex() Exemple import java.util.*; public class TestList {// 1 3 5 7 9 9 7 5 3 1 public static void main (String argv[]) { List l = new LinkedList(); for(int i=0;i<10;i++) l.add(i,new Integer(i)); for(int i=0;i<10;i=i+2) l.remove(new Integer(i)); ListIterator iter = l.listIterator(); while(iter.hasNext()) System.out.print(“ “+iter.next()); while(iter.hasPrevious()) System.out.print(“ “+iter.previous()); }} © B. Carré Polytech’Lille 16 Les ensembles : java.util.Set Tout comme les List, les Set implémentent l’interface Collection mais interdisent les doublons au sens de equals: ∀o1,o2, !o1.equals(o2) Cette propriété est vérifiée lors des ajouts mais elle n’est pas maintenue, la modification d’objets peut la rendre caduque : deux éléments peuvent devenir égaux («aliasing ») Contrairement aux List l’ordre des éléments est interne et donc pas d’accès direct. Il existe principalement deux sortes de Set : TreeSet et HashSet © B. Carré Polytech’Lille 17 HashSet / TreeSet HashSet Les éléments sont rangés de façon hachée par appel de leur méthode hashCode() (de Object, redéfinissable). Les performances de HashSet sont meilleures que TreeSet. TreeSet Ou ensembles ordonnés, les éléments sont rangés dans un arbre ordonné, ce qui assure des manipulations en log(n). L’ordre des éléments est : © B. Carré soit leur ordre naturel (compareTo de Comparable) si aucun Comparator n’est founi au constructeur. La classe des éléments doit alors implémenter Comparable. soit déterminé par un Comparator d’éléments fourni à l’instanciation: public TreeSet(Comparator c) Polytech’Lille 18 Set : exemple Un ensemble d’ouvrages ordonné selon leur ordre naturel (par auteur) construit sur le tableau t1 de la section Arrays TreeSet ensemble = new TreeSet(Arrays.asList (t1)); ensemble.add(new Ouvrage(“Parapente”,”Ali Gali”)); Iterator iter = ensemble.iterator(); while (iter.hasNext()) System.out.println (iter.next()); /* resultats Parapente Ali Gali Java Eckel C Kernighan Germinal Zola */ © B. Carré Polytech’Lille 19 Les utilitaires de la classe Collections Tout comme Arrays la classe Collections offre les mêmes utilitaires (static) sur les List : tri : sort recherche ordonnée : binarySearch sur ordre naturel ou par Comparator Ces méthodes ont les mêmes profils que dans Arrays mais sont paramétrées par des List : Exemple: public class Collections public static void sort(List list) Ces opérations permettent de trier des listes (épisodiquement) de l’extérieur Contrairement aux TreeSet maintenues ordonnées en interne (sauf aliasing...). © B. Carré Polytech’Lille 20 Les tables d’association : java.util.Map Elles permettent de maintenir des associations clé-valeur (Object-Object). On retrouve les opérations semblables à HashTable spécifiées dans une interface commune Map: public interface Map public Object put(Object key, Object value) throws NullPointerException public Object get(Object key) public Set keySet() // l’ensemble des cles public Collection values() // l’ensemble des valeurs ... Il existe principalement deux sortes de tables : les HashMap et les TreeMap qui implémentent cette interface. © B. Carré Polytech’Lille 21 HashMap / TreeMap HashMap nouvelle version de HashTable (toujours disponible). Tout comme Hashtable elles utilisent la méthode hashCode() des objets clés. l’ensemble des clés est un HashSet. Les performances de HashMap sont meilleures que TreeMap. TreeMap permet de gérer des tables ordonnées (contrairement aux Hashtable) sur les clés. l’ensemble des clés est un TreeSet (arbre binaire ordonné assurant un accès en log(n). les clés doivent donc être ordonnables soit en implémentant Comparable (ordre naturel) soit en fournissant un Comparator au constructeur : public TreeMap(Comparator c) © B. Carré Polytech’Lille 22 TreeMap : exemple Bibliothèque (table code-ouvrage) ordonnée par les codes (String) public class Bibliotheque { private TreeMap ouvrages = new TreeMap(); // ordre naturel (String) public void add(String code, Ouvrage o) { ouvrages.put(code,o);} // ajout ordonné int compteurTotal() {// parcours des elements int total=0; Iterator iter = ouvrages.values().iterator(); while (iter.hasNext()) total=total+((Ouvrage)iter.next()).getCompteur(); return total; } public void listing() {// parcours des cles (ordonné) Iterator codes = ouvrages.keySet().iterator(); while (codes.hasNext()) { Object code = codes.next(); System.out.println(code+”:”+ouvrages.get(code)); } ... }} © B. Carré Polytech’Lille 23 TreeMap : exemple (suite) // application Bibliotheque bib = bib.add(“I101”,new bib.add(“L202”,new bib.add(“S303”,new bib.add(“I345”,new bib.listing(); new Bibliotheque(); Ouvrage(“C”,”Kernighan”)); Ouvrage(“Germinal”,”Zola”)); Ouvrage(“Parapente”,”Ali Gali”)); Ouvrage(“Java”,”Eckel”)); /* resultat : ordre lexicographique des codes I101:C Kernighan I345:Java Eckel L202:Germinal Zola S303:Parapente Ali Gali */ © B. Carré Polytech’Lille 24