Vous êtes sur la page 1sur 9

2

Algorithmique et Les collections


Programmation Orientée Objet
en Java en Java

2e année – Chapitre 5 : Les collections Java


Notion de généricité
Version 20.0306

Les collections en Java 3


Le package java.util 4

À quoi servent les collections ? • Structuration générale


• Basée sur une hiérarchie d’interfaces
• Stocker des données • Organisée par types
• Autrement que dans de simples tableaux
à des structures de taille dynamique • Manipulation unifiée
à des structures adaptées au besoin • Indépendant du type concret de la structure
• Sans réinventer la roue • Algorithmes de base fournis
• Gagner du temps et de l’énergie • Recherche d’élément
• Bénéficier de classes robustes et performantes • Tri de la collection
• etc.
• Fournies par Java en standard
• Dans le package java.util
Le package java.util 5
L’interface Collection 6

• Principales méthodes
• int size()
• boolean isEmpty()
• boolean add(Object o)
• boolean remove(Object o)
• boolean contains(Object o)
• void clear()
• Iterator iterator()

• Exemples de classes l’implémentant


• ArrayList, LinkedList : différents types de liste
• Ce n’est qu’un aperçu : plus de détails, plus de documentation • TreeSet, HashSet : différents types d’ensemble
à cf. API Java sur le web

L’interface Iterator 7
Utilisation d’itérateur 8

• Spécifie les caractéristiques d’un « itérateur » // Exemple de parcours d’une collection


public static void main(String[] args) {
• Énumère les éléments d’une collection Collection c = new HashSet();
c.add("un");
à pour écrire une itération
c.add("deux");
• Parcours dans un seul sens c.add("trois");
• Disponible pour toute collection
Iterator it = c.iterator();
à via la méthode iterator() imposée par l’interface Collection while (it.hasNext()) {
System.out.println(it.next());
• Principales méthodes d’un itérateur }
}
• boolean hasNext()
• Object next() throws NoSuchElementException
• L’exception (éventuellement) lancée dérive de RuntimeException trois
un
deux
La méthode next() de l’itérateur 9
Utilisation implicite d’itérateur 10

Iterator it = c.iterator();
while (it.hasNext()) {
• Utilisation du « for each »
System.out.print(it.next().getClass()); • Fonctionne pour tous les objets implémentant l’interface
System.out.println(" - " + it.next()); Iterable (en particulier les collections)
}
public static void main(String[] args) {
class java.lang.String - un Collection c = new HashSet();
class java.lang.String c.add("un");
Exception in thread "main" java.util.NoSuchElementException c.add("deux");
c.add("trois");
Iterator it = c.iterator();
while (it.hasNext()) {
for (Object o : c) { // for each Object o in c
Object o = it.next(); // Pour ne faire qu’un seul next()
System.out.println(o.getClass() + " - " + o);
System.out.println(o.getClass() + " - " + o);
}
}
}
class java.lang.String - trois
class java.lang.String - un class java.lang.String - trois
class java.lang.String - deux class java.lang.String - un
class java.lang.String - deux

L’interface List 11
L’interface Set 12

• Spécifie les caractéristiques d’une liste • Spécifie les caractéristiques d’un ensemble
• Suite de données ordonnées (et indexées à partir de 0) • Ensemble de données non ordonnées (cf. maths)
• Pouvant contenir des doublons • Sans doublons

• Principales méthodes (en + de celles imposées par Collection) • Principales méthodes


• void add(int index, Object o) • Celles de Collection
• Object get(int index)
• Object remove(int index) • Exemples de classes l’implémentant
• int indexOf(Object o) • HashSet : temps constant pour les opérations de base
• TreeSet : éléments rangés selon leur ordre naturel
• Exemples de classes l’implémentant
• ArrayList : liste dans un tableau, accès rapide
• LinkedList : liste chaînée, insertion/suppr. rapides
L’interface Map 13
Algorithmes fournis 14

• Spécifie les caractéristiques d’un « dictionnaire » // Recherche dans une liste


public static void main(String[] args) {
• Ensemble de couples (clé, valeur) List l = new LinkedList();
l.add("titi");
• Clés uniques, Couples non ordonnés l.add("toto");
l.add("tata");
• Principales méthodes
int index = Collections.binarySearch(l, "toto");
• Object put(Object key, Object value) System.out.println("Index = " + index);
• boolean containsKey(Object key) }

• Object get(Object key) Index = 1

• Set keySet()
• Collection values()
• D’autres algorithmes de la classe Collections
• min(l),max(l),sort(l),reverse(l),shuffle(l)…
• Exemples de classes l’implémentant
• HashMap, TreeMap

Exemple : tri d’une liste 15


Exercice : Library 16

public static void main(String[] args) {


List l = new ArrayList();
• Modélisation d’une bibliothèque
l.add(2); • Écrire la classe Library correspondant au diagramme de
l.add(3); classes suivant :
l.add(1);
for (Object o : l) {
System.out.println(o);
}
2 )
3
1

Collections.sort(l); *
for (Object o : l) {
System.out.println(o);
}
1
} 2
3
Solution 17 18

public

Notion de généricité

en Java

Des collections génériques 19


Notion de généricité 20

• Désormais : préciser le type de la collection • Motivation


• Plus une collection quelconque • On ne va pas réécrire autant de classes que de types de
• à Mais une collection de « quelque chose » contenu possible à fournir un modèle
• Indiquer le type des objets qui seront dans la collection
• Exemple : List<String> l = new ArrayList<String>(); • Concept : généricité = abstraction supplémentaire
• Représenter par une seule classe (le modèle)
• Intérêts des collections génériques toute une famille de variantes
• Améliorer la lisibilité et la compréhension • Avec les mêmes algorithmes de méthodes
• Mais dont seulement un ou plusieurs types diffèrent en entrée
• Gagner en sécurité
• Le type des objets ajoutés à la collection est vérifié dès la compilation • C’est un type paramétré par un autre type
• Pas besoin de contrôler le type à l’exécution avec instanceof
• Exemple : on définit ArrayList<E> pour permettre
• des ArrayList<Integer>, des ArrayList<String>, des ArrayList<Document>
• etc.
L’interface Collection<E> 21
Généricité des collections Java 22

• Principales méthodes • Les interfaces deviennent génériques


• int size() public interface List<E> {
void add(E x);
• boolean isEmpty() Iterator<E> iterator(); ArrayList<E>

• boolean add(E o) }
• boolean remove(E o) public interface Iterator<E> { + ArrayList()
• boolean contains(E o) E next(); + void add(E e)
boolean hasNext(); + E remove(int index)
• void clear() } …
• Iterator<E> iterator()

• Exemples de classes l’implémentant • Les classes abstraites deviennent génériques


• ArrayList<E>, … • Les classes concrètes deviennent génériques
• TreeSet<E>, …

Comparaison 23
Remarque sur la généricité Java 24

• Avec ou sans généricité ? • Un type générique Java engendre un unique type


List l = new ArrayList(); public static void main(String[] args) {
• Sans : l.add(42); List<String> ls = new ArrayList<String>();
l.add('f'); List<Integer> li = new ArrayList<Integer>();
l.add("toto");
int i; System.out.println(ls.getClass() == li.getClass());
if (l.get(0) instanceof Integer) {
i = (Integer) l.get(0); System.out.println(ls.getClass().getName());
} System.out.println(li.getClass().getName());
}

List<Integer> l = new ArrayList<Integer>(); true


• Avec : l.add(42);
java.util.ArrayList
java.util.ArrayList
l.add('f'); // The method add(Integer) in the type
List<Integer> is not applicable for the arguments (char)
int i = l.get(0); • D’autres langages conservent bien la notion d’engendrer toute une
famille de types, distincts les uns des autres
Héritage et généricité 25
Wildcard <? extends Type> 26

• Pas d’héritage lié au type paramètre • Bénéficier du polymorphisme avec type paramétré
• Même si Rectangle hérite de Figure • Autoriser plusieurs types effectifs pour la collection
• List<Rectangle> n’hérite pas de List<Figure> • Imposer une contrainte d’héritage sur le contenu

• Justification • Exemple : List<? extends Figure>


• Mènerait à de possibles contradictions public static void main(String[] args) {
List<Rectangle> liste = new ArrayList<Rectangle>();
public static void main(String[] args) {
List<String> listString = new ArrayList<String>(); liste.add(new Rectangle());
List<Object> listObject = listString; // refusé liste.add(new Carre());
listObject.add(new Object()); dessinerTout(liste);
String s = listString.get(0); // sinon contradiction ici !!! }
}

Type mismatch: cannot convert from List<String> to List<Object> public static void dessinerTout(List<? extends Figure> lf) {
for (Figure f : lf) {
f.dessiner();
}
}

L’interface Comparator<E> 27
Exercice : comparateur 28

• Spécifie les caractéristiques d’un « comparateur » • Créer un comparateur qui permettra d’ordonner
• Objet spécifique selon le 1er auteur (utilisé lors d’un tri)
• pour faire des comparaisons entre 2 objets de type E
• Permet d’ajouter la comparaison à des objets n’ayant pas
de relation d’ordre naturelle
• Permet de comparer suivant n’importe quel critère
• Exemple : utilisé comme 2e paramètre de la méthode Collections.sort()

• Principale méthode à implémenter


• int compare(E e1, E e2)
• Renvoie un <0 si e1<e2 Indication
• Renvoie un 0 si e1 égale e2 • Les objets String possèdent une relation d’ordre naturelle via leur
méthode : int compareTo(String)
• Renvoie un >0 si e1>e2
Solution 29
Créer une classe générique 32

• Rajouter un paramètre de type


public
• C’est un type formel, pour l’instant inconnu,
qui sera utilisé par notre classe
• Exemple : Solo<T>

• Intérêt de définir une classe générique


• (Ré)utiliser un même modèle dans plusieurs cas
} • Ne pas utiliser le type trop général Object lorsque le type
réel est inconnu pour l’instant, mais fixé à l’utilisation
• Améliorer la lisibilité et la compréhension
• Gagner en sécurité

Exemple de classe générique 33


Exercice : Duo 34

public class Solo<T> {


private T valeur; • Créer une classe Duo<T,S> inspirée de la classe
public Solo() {
Solo<T>
this.valeur = null;
}

public Solo(T val) {


this.valeur = val;
}

public void setValeur(T val) {


this.valeur = val;
}

public T getValeur() {
return this.valeur;
}
}
Solution 35

public class

Vous aimerez peut-être aussi