Vous êtes sur la page 1sur 87

UEF4.3.

Programmation
Orientée Objet

Mme SADEG & Mme BOUSBIA


{s_sadeg , n_bousbia}@esi.dz
Ecole nationale Supérieure d’Informatique
(ESI)
2

Cours précédent
•Partie 1. L’héritage
▫La notion d’héritage
▫Accès d’une classe dérivée aux membres de sa classe de base
▫Construction des objets dérivés
▫Initialisation d’un objet dérivé
▫Dérivations successives
▫La notion de redéfinition d’une méthode
▫Redéfinition de méthode et dérivations successives
▫Surdéfinition et héritage
▫Contraintes portant sur la redéfinition
▫Duplication des champs
3

Cours précédent
•Partie 2. Le polymorphisme
▫La notion de polymorphisme
▫Les bases du polymorphisme
▫Généralisation du polymorphisme à plusieurs classes
▫Polymorphisme, redéfinition et surdéfinition
▫Conversion des arguments effectifs
▫Les règles de polymorphisme en java
▫Conversion explicite de référence
▫La super-classe Object
▫Héritage et tableaux
▫Polymorphisme et tableaux
▫Les classes abstraites
▫Les interfaces
Chapitre IV

Partie 1. Les Tableaux


5

Tableaux
• Un tableau est une structure de données qui stocke
une série de n valeurs de même type (élémentaire
ou objet)
▫ Il peut être utilisé comme une variable, un argument ou
un type de retour d’une méthode

• L’accès à chaque valeur se fait avec un indice entier


▫ Soit « tab » un tableau d’entiers
▫ tab[i] est le ième entier du tableau
▫ En Java i varie de 0 à n-1 (n est la taille du tableau)
▫ L’accès à la case « n » provoquera une erreur!
6

Déclaration et Initialisation
• Pour définir un tableau d’entier on peut écrire:
int[] a; ou int a[];
▫ Cette instruction ne déclare que la variable « a »
• L’opérateur « new » crée le tableau:
a=new int[100];
int a[]=new int[100];
• On peut aussi créer un tableau et l’initialiser simultanément
avec ses valeurs
int[] nbrPremiers= {2, 3, 5, 7};
• Il est même possible d’initialiser un tableau anonyme:
new int[] {11, 13, 17, 19};
• Cette syntaxe est employée pour réinitialiser un tableau sans
créer une nouvelle variable
nbrPremiers =new int[] {11, 13, 17, 19};
7

Taille et Parcours d’un tableau


• On peut récupérer la taille d’un tableau à l’aide de
nomduTableau.length

• Pour remplir ou parcourir un tableau nous pouvons utiliser


une boucle:
for (int i = 0; i < a.length; i++)
System.out.println(a[i]);

• Remarque:
▫ Il est légal en Java d’avoir un tableau de taille 0, qui est
différent de null.
▫ Cela est utile dans le cas d’une méthode qui retourne un
tableau comme type de retour
8

Copie des tableaux


• Quel est le résultat de la copie d’une variable tableau
dans une autre?
int[] nbr= nbrPremiers;
nbr[2]=31;//nbrPremiers[2]= 31
2
nbrPremiers 3

nbr 31

7
Les deux variables font référence au même
tableau
9

Copie des tableaux


• Pour copier toutes les valeur d’un tableau dans
un autre, il faut employer la méthode
arraycopy de la classe System
System.arraycopy(source, indiceSource, cible, indiceCible, compte)

• Exemple
int[] ta= {2, 3, 5, 7};
int[] tb={1,10,100,1000,1010,1100};
System.arraycopy(ta,1,tb,2, 3);
for (int i = 0; i < tb.length; i++)
System.out.print(tb[i]+" ");
• Résultat? 1 10 3 5 7 1100
10

Tableaux multidimensionnels
• Les tableaux multidimensionnels sont des tableaux de tableaux

• Ils utilisent plusieurs indices pour accéder aux éléments

• Exemple: supposons que nous voulons manipuler une matrice


(Tableau à 2 dimensions)

double[][] mat=new double[3][2];


Ou
double[][] mat={{1,6},{5,8},{1.5,7}};

• Parcours
for (int i = 0; i < mat.length; i++)
for (int j = 0; j < mat[i].length; j++)
System.out.print(mat[i][j]+" ");
11

Tableaux Irréguliers
• Un tableau irrégulier est un tableau
multidimensionnel où les différentes rangées ont
des longueurs différentes (sous tableaux de taille
différentes)
▫ Exemple: Matrice triangulaire
12

Tableaux Irréguliers
• Pour créer un tableau irrégulier (Ex. matrice
triangulaire) , nous commençons par créer le
tableau qui contient les rangées
▫ double[][] mat=new double[3][];
• Ensuite créer les rangées de la matrice triangulaire
for (int i = 0; i < mat.length; i++)
mat[i]= new int[i+1];
• Une fois le tableau alloué, nous pouvons remplir et
accéder à ses éléments à condition de ne pas
dépasser les limites de chaque sous tableau
13

Classe Arrays
• Le package java.util définit une classe, Arrays,
propose des méthodes statiques (de classe)
utilitaires pour travailler avec des tableaux d’objets
ou de types primitifs (les méthodes sont surchargées
pour tous les types primitifs)
▫ Comparer 2 tableaux : equals et deepEquals
▫ Représenter un tableau sous forme de String: toString
▫ Copier un tableau (depuis 1.6) : copyOf
 Rappel : System.arraycopy permet de copier les éléments
d’un tableau dans un tableau existant
14

classe Arrays
• Des méthodes de recherche
▫ int binarySearch(char[ ] a) , int binarySearch(int[ ] a) …
int binarySearch(Object[ ] a)
• Des méthodes de tris
▫ sort(char[ ] a) , sort(int[ ] a) ….. sort(Object[ ] a)
▫ sort(char[ ] a, int fromIndex, int toIndex) , ...
• Des méthodes pour remplissage avec une valeur
▫ fill(char[ ] a, char val) , fill(int[ ] a, long val) …..
▫ fill(char[ ] a, int fromIndex, int toIndex, char val)…
• Des méthodes de test d’égalité
▫ boolean equals(char[ ] a1, char[ ] a2),
▫ boolean equals(int[ ] a1,int[ ] a2), …..
15

Tri d’un tableau


• Pour le tri d’un tableau on utilise la méthode
statique sort de la classe Arrays

• Exemple:
double[] vec = new double[1000];
for (int i = 0; i < vec.length; i++)
vec[i] = Math.random()*1000;
// tri du tableau
Arrays.sort(vec);
16

Recherche dans un tableau


• Pour la recherche dans un tableau trié on
utilise la méthode statique binarySearch de
la classe Arrays

▫ Elle retourne l’indice de la valeur v trouvée

▫ Sinon une valeur négative pos, où (-pos-1)


indique la position à laquelle v devrait être
insérée
17

Recherche dans un tableau


•Exemple:
int[] vec = new int[1000];
for (int i = 0; i < vec.length; i++)
vec[i] = (int) (Math.random()*1000);
// recherche de la valeur 500
Arrays.sort(vec);
int pos = Arrays.binarySearch(vec,500);
if (pos >= 0)
System.out.println("position de 500 : " + pos);
else
System.out.println("500 n’est pas dans le
tableau, vous pouvez l’insérer à la case"+ (-pos-
1));
18

Y a-t-il d’autres structures d’ensembles?

• Les tableaux sont des structures de données


élémentaires
• Le package java.util contient plein de classes
pour la gestion de structures de données plus
évoluées :
▫ listes
▫ ensembles
▫ arbres
Il s’agit des Collections!
Chapitre IV

Partie 2. Les Collections


20

Plan du cours
• Qu’est ce qu’une collection?
• Cadre des collections en Java
• Description des interfaces du framework
▫ Interface Collection
 Parcourir une collection: les itérateurs
 Les ensembles: interface Set
 Les listes: interface List
 Les Files: interface Queue
▫ Interface Map: Les tableaux associatifs
21

Qu’est ce qu’une collection?


• Une collection est un conteneur d’objets : C’est
un objet dont la principale fonctionnalité est de
contenir d’autres objets, comme un tableau

• Avant le JDK 5.0 les objets contenus dans une


collection étaient tous considéré de type « Object »
• Il n’était pas possible d’indiquer qu’une collection ne
Lacontenait
notion dequegénéricité
des objets d’un certain
permet de type
définir des
modules paramétrés par le type qu'ils manipulent.
• A partir du JDK 5.0, on peut indiquer le type des objets
contenus dans une collection grâce à la généricité :
List<Employe>
22

Qu’est ce qu’une collection?


• Il est préférable d’utiliser les collections génériques:
• Une collection est un objet qui représente un
groupe d’éléments de type E

• Dans les premières versions de Java, les collections


étaient représentées par les classes
"Array","Vector","Stack" etc.

• Puis avec Java 1.2 (Java 2), est apparu le frameWork


(cadre) de collections Java :
• La bibliothèque des classes pour les collections
23

Cadre de Collections Java


• Ce cadre définit:
▫ Des interfaces: qui représentent les collections
▫ Des classes abstraites: qui implantent les méthodes
de base communes aux interfaces.
▫ Des réalisations (implémentations) : réalisations
concrètes des interfaces en s’appuyant sur différentes
solutions pour stocker les éléments (tableau, structures
chaînées, table de hachage, arbre, etc.).
▫ Des algorithmes : algorithmes classiques (chercher, trier,
etc.) polymorphes (fonctionnent avec plusieurs collections)
▫ Un protocole d’itération : pour parcourir une
collection du début à la fin.
24

Hiérarchie des Collections en Java

• Remarque : Vector est une « ancienne » classe qui a été


modifiée pour faire partie de la hiérarchie Collection.
25

Les interfaces
• Le cadre est composé de 10 interfaces définies
dans le paquetage java.util. Chacune définie:
▫ un type (liste, ensemble, file, tableau associatif, etc.)
▫ les opérations disponibles sur ce type
▫ la sémantique des opérations (informelle: pas de code)

• Il existe deux interfaces fondamentales :


▫ Collection <E>: correspond aux interfaces des
Iterable Iterator
collections proprement dites
▫ Map <K,V> : correspond aux collectionsCollection
indexées
Map

par des clés


Set List Queue
SortedMAp

SortedSet Deque
26

Les classes abstraites


• AbstractCollection<E>, AbstractList<E>,
AbstractMap<K,V>,… implantent les
méthodes de base communes aux interfaces
Collection ou Map

• Elles permettent de factoriser le code commun à


plusieurs types de collections et à fournir une
base aux classes concrètes du JDK et aux
nouvelles classes de collections ajoutées par les
développeurs
27

Les réalisations (classes concrètes)


• ArrayList<E>, LinkedList<E>,
HashSet<E>, TreeSet<E>,
HashMap<K,V>, TreeMap<K,V>,… héritent
des classes abstraites
• Elles ajoutent les supports concrets qui vont
recevoir les objets des collections (table de
hachage, liste chaînée,…)
• Elles implantent ainsi les méthodes d’accès à ces
objets (get, put, add,…)
28

Les réalisations (classes concrètes)


• Le framework fournit les implémentations
suivantes des différentes interfaces:

Set List Map


  collection d'éléments collection avec collection sous la
uniques doublons forme clé/valeur

ArrayList,
Tableau redimensionnable   Vector (JDK  
1.1)
Arbre TreeSet   TreeMap
Liste chaînée   LinkedList  
HashMap,
Collection utilisant une table
HashSet   HashTable
de hashage
(JDK 1.1)
Classes du JDK 1.1   Stack (pile)  
29

Classes utilitaires
• La classe Collections (avec un s à la fin) fournit
des méthodes statiques pour, en particulier
▫ trier une collection
▫ faire des recherches rapides dans une collection triée

• La classe Arrays fournit des méthodes statiques


pour, en particulier
▫ trier un tableau
▫ faire des recherches rapides dans un tableau trié
▫ transformer un tableau en liste
30

Classes utilitaires: Classe Collections


• Contient des méthodes statiques pour
▫ trier les éléments d’une collection : sort
▫ Chercher des éléments : binarySearch (nécessite une relation
d’ordre)
▫ Compter le nombre d’occurrences d’un élément : frequency
▫ Vérifier si deux collections sont disjointes : disjoint
▫ Trouver le min et le max (nécessite une relation d’ordre).
▫ manipuler des données :
 reverse : inverser l’ordre des éléments d’une List
 fill : remplacer tous les éléments d’une List par une valeur
 copy : copier les éléments d’une liste source vers une liste
destination
 swap : permuter les éléments de deux listes
 addAll : ajouter des éléments à une collection
31

Exemple
Collection<String> l = new ArrayList<String>();
l.add("Mohammed Ahmed");
l.add("Meriem Mehdi");
l.add("Mehdi Khettab");
l.add("Ahmed Mohammed");
Collections.sort(l);
System.out.println(l);
int n=Collections.binarySearch(l, "Meriem
Mehdi");
System.out.println("Meriem Mehdi est à la
position "+n+" de la liste");
Résultat:
[Ahmed Mohammed, Mehdi Khettab, Meriem Mehdi, Mohammed Ahmed]
Meriem Mehdi est à la position 2 de la liste
32

Collections du JDK 1.1


• Le JDK 1.1 fournit les classes et interfaces
suivantes:
▫ Vector
▫ HashTable
▫ Enumeration
• Elles existent encore mais il vaut mieux utiliser les
nouvelles classes vu qu’elles offrent plus de
possibilités et de bonne performances.
• Il est cependant utile de les connaître car elles sont
utilisées dans d’autres API du JDK
• Elles ne seront pas étudiées ici en détails
33

Description des interfaces du


framework
34

L’Interface Collection
35

L’interface java.util.Collection
• L’interface Collection est la racine de l’arbre
d’héritage des structures de données de Java.

• Aucune classe du JDK n’implante directement


cette interface (les collections vont implanter des
sous-interfaces de Collection, par exemple
List)
36

L’interface java.util.Collection
• Propriétés :
▫ Avant Java 1.5, les éléments d’une collection était
Object.
▫ Une collection peut autoriser ou non plusieurs
occurrences d’un même élément (List vs Set).
▫ Les éléments peuvent être triés ou non (Set vs
SortedSet).
▫ Toute réalisation d’une Collection doit définir :
 un constructeur par défaut (qui crée une collection vide)
 un constructeur qui prend en paramètre une collection
d’éléments de type compatible en paramètre
(conversion).
37

L’interface java.util.Collection<E>
public interface Collection<E> extends Iterable<E>{
// Operations Basiques
public int size();
public boolean isEmpty
public boolean contains (Object o);
public boolean add (E o);
public boolean remove(Object object
public Iterator<E> iterator();

//Opération sur les ensembles
public boolean containsAll (Collection<?> c);
public boolean addAll(Collection<? extends E> c);
public boolean removeAll(Collection<?> c);
public boolean retainAll(Collection<?> c) ;
public void clear ();

//Opérations sur les tableaux
public Object[] toArray();
public <T> T[] toArray(T[] a);
}
38

L’interface java.util.Collection
• Opérations basiques :
• size: retourne le nombre d’éléments dans la
collection
• isEmpty(): retourne true si la collection est vide
• contains (Object o) : retourne true si la collection
l’objet o (basé sur la méthode equals de la classe E)
• add (E o): ajoute l’élément o à la collection.
Retourne false si doubles interdits
• remove(Object object): supprime l’objet o
• iterator(): retourne l’itérateur de la collection
39

L’interface java.util.Collection<E>
• Exemple: Soit c une
référence vers une collection vide

Point p1 = new Point(0,0);


c.add(p1);
c.add(new Point(10,10));

c.contains(p1); //True

Point p2 = new Point(0,0);


c.contains(p2); //False

• La méthode equals exécutée est celle de la classe Point héritée de la super


class Object, définie par :
public boolean equals(Object o) {
return this == o;
}
40

L’interface java.util.Collection<E>
• Si on redéfinit la méthode equals de Object dans la classe Point :

public class Point {



public boolean equals(Object o){
if (!(o instanceof Point)
return false;
Point p = (Point) o;
return this.x == p.x &&
this.y == p.y;
}

• Le résultat de l’instruction devient


c.contains(p2) --> true
41

L’interface java.util.Collection
• Opérations sur les ensembles :
• containsAll (Collection<?> c): retourne true si la
collection contient tous les éléments de c (Les
éléments de c doivent être de type E ou un sous
type de E)
• addAll(Collection<? extends E> c): ajoute les
éléments de c (union)
• removeAll(Collection<?> c): supprim tous les
éléments de c (différence)
• retainAll(Collection<?> c): conserve les éléments de
c (intersection)
• clear (): supprimer tous les éléments de la collection
42

L’interface java.util.Collection
• Transformation en tableaux :
▫ toArray(): renvoie une instance de Object[] qui
contient les éléments de la collection
▫ T[] toArray(T[] a): renvoie un tableau d’un
type T compatible avec le type de la collection à
laquelle on passe en paramètre un tableau « a » du
type voulu:
 si le tableau « a » est assez grand, les éléments de la
collection sont rangés dans le tableau
 sinon, un nouveau tableau du même type est créé
pour recevoir les éléments de la collection
43

Transformation en Tableau
Exemple: Soit une collection « c » de String:
• Pour obtenir un tableau d’objets:
Object[] tableau = c.toArray();

 Remarque : si la collection est vide, toArray


renvoie un tableau de taille 0 (pas la valeur null)

• Pour obtenir un tableau de type String[]


String[] tableau = c.toArray(new String[0]);
44

Collections et types primitifs


• Les collections de java.util ne peuvent pas contenir
de valeurs des types primitifs

• Avant le JDK 5, il fallait donc utiliser explicitement


les classes enveloppantes des types primitifs (exp:
Integer, Double, etc.)

• A partir du JDK 5, les conversions entre les types


primitifs et les classes enveloppantes peuvent être
implicites avec le « boxing » / « unboxing »
(envelopper/déballer)
45

Exemple
• Exemple de liste avec • Exemple de liste sans
(un)boxing (un)boxing (avant jdk5)
List<Integer> l = new List l = new ArrayList();
ArrayList<Integer>(); l.add(new Integer(10));
l.add(10); l.add(new Integer(-678));
l.add(-678); l.add(new Integer(87));
l.add(87); l.add(new Integer(7));
l.add(7); int i = l.get(0).intValue();
int i = l.get(0);
46

Parcourir une Collection


Les itérateurs
47

Qu’est ce qu’un « Itérateur »?


• Un itérateur (instance d’une classe qui implante
l’interface Iterator<E>) permet d’énumérer les
éléments contenus dans une collection
▫ Il encapsule la structure de la collection
▫ Permet de parcourir tous les éléments d’une
collection (en analogie avec le parcours d’un
tableau).
48

Qu’est ce qu’un « Itérateur »?


• Pour pouvoir itérer sur une collection, il faut qu'elle
soit itérable, c'est à dire qu'elle hérite de Iterable.
public interface Iterable<E> {
Iterator<E> iterator();
}

• L’interface « Collection » dérive de l’interface


« Iterable »

• Toutes les collections implémentent une méthode


iterator() qui renvoie un itérateur
49

L’interface java.util.Iterator<E>
• Cette interface définit des méthodes pour des
objets capables de parcourir les données d'une
collection:
▫ boolean hasNext(): retourne true s'il reste au moins
un élément à parcourir dans la collection
▫ E next(): renvoie l'élément courant dans le
parcours et passe l'itérateur à l'élément suivant
(lance NoSuchElementException lorsqu’il n'y a plus
rien à renvoyer)
▫ void remove(): supprime le dernier élément
parcouru (next doit être appelé avant)
50

L’interface java.util.Iterator<E>
• Exemple: parcourir une collection
Collection<Point> c ;
….
Iterator<Point> it = c.iterator();
while (it.hasNext()) {
Point p1 = it.next(); // retourne l’élément
courant et avance
// manipuler élément...
}
51

L’interface java.util.Iterable<E>
• Il est aussi possible d’utiliser foreach pour
parcourir la collection
Iterable<E> collection = ......;
for (E o : collection){
…;
}

Iterable<E> collection = ...


Iterator<E> it = collection.iterator();
while ( it.hasNext() ){
E o = it.next();

}
52

Les ensembles
Interface Set<E>
53

L’interface java.util.Set<E>
• Correspond à une collection qui ne contient pas 2
objets égaux au sens de equals (comme les
ensembles des mathématiques)

• Les ajouts d'éléments déjà présents sont donc


ignorés.
▫ Un élément est déjà présent si un test equals sur un
des éléments de l'ensemble renvoie vrai.

▫ Attention! La non duplication d’objets n’est pas


assurée dans le cas où on modifie les objets déjà ajoutés
54

Méthodes de l’interface Set<E>


• Mêmes méthodes que l’interface Collection
▫ Mais les méthodes sont adaptées aux ensembles

• Par exemple,
▫ la méthode add n’ajoute pas un élément si un
élément égal est déjà dans l’ensemble (la méthode
renvoie alors false)
55

Interfaces dérivées du Set


• SortedSet<E>
▫ Un Set qui ordonne ses éléments
▫ Des méthodes sont ajoutées à Set, liées à l’ordre
total utilisé pour ranger les éléments (first(),
last(), comparator(), subSet(E debut, E fin),
headSet(E fin), tailSet(E debut))

• NavigableSet<E>
▫ Interface du JDK 6 dérivée de SortedSet
▫ Permet de naviguer dans un Set à partir d’un de ses
éléments, dans l’ordre du Set ou dans l’ordre inverse
56

Implémentations du Set
• HashSet<E> implémente Set avec une table de hachage ;
▫ Cette classe ne vérifie l’égalité que pour les objets qui ont le
même hashCode (méthode de la classe Object)
« 2 objets égaux au sens de equals doivent avoir la même valeur
pour la méthode hashCode »

• TreeSet<E> implémente NavigableSet avec un arbre


ordonné
▫ stocke ses objets dans un arbre binaire
▫ les éléments sont rangés dans leur ordre naturel (interface
Comparable<E>) ou suivant l’ordre d’un Comparator<?
super E> passé en paramètre du constructeur
57

Exemple
• On souhaite créer une classe AgenceBancaire
permettant de gérer un ensemble de comptes
bancaires.
• On souhaite pouvoir ajouter un compte, s’il
n’existe pas, supprimer un compte, rechercher
un compte par le nom du client, …
• Les comptes doivent être triés par leur numéro.
58

Exemple
public class Compte implements
Comaprable{
private String nom; public void supprimerCpt(Compte c){
private String numero; lesComptes.remove(c);
private double solde; }
//… public Compte rechercherCpt(String
public int compareTo(Object c) { nom){
String num=(Compte)c).getNum(); Compte c=null;
return this.numero.compareTo(num); Iterator<Compte> it =
} lesComptes.iterator();
}//fin de la classe Compte while (it.hasNext()){
c=it.next();
public class AgenceBancaire { if
private Set<Compte> lesComptes; (nom.equalsIgnoreCase(c.getNom()))
return c;
public AgenceBancaire () { }
lesComptes = new TreeSet<Compte>(); return null;
} }
public boolean ajouterCpt(Compte c){ //…
return lesComptes.add(c); }//fin de la classe Agence
}
60

Exercice 1: Partie 1 – Ensembles


1. Créez une classe Animal (chaque animal a un nom), et une classe Main instanciant
un ensemble d'animaux (sous forme d'un HashSet).
3. Peuplez votre ensemble d'animaux.
4. Affichez l'ensemble d'animaux en utilisant l'littérateur fourni par la méthode
Iterator().
5. Indiquez que deux animaux sont égaux s'ils ont le même nom en redéfinissant la
méthode equals de la classe Animal en la surchargeant de la façon suivante :
equals(Animal a) (au lieu de equals(Object o)).
6. Ajoutez plusieurs animaux ayant le même nom.
7. Affichez de nouveau. Que constatez-vous ? Cela correspond-il à la spécification de
Set ?
8. Commentez la méthode equals(Animal a) et redéfinissez equals(Object o). Cela
résout-il le problème ?
9. Redéfissiez la méthode hashCode de la classe Animal de façon qu'elle renvoie le
hashCode du nom de l'animal. Cela résout-il le problème ?
10. Transformez le support physique de l'ensemble d'animaux en un TreeSet. Que
faut-il rajouter à la classe Animal ? Pourquoi ?
61

Les listes
Interface List<E>
62

L’interface java.util.List<E>
• L’interface List<E> correspond à une collection
d’objets indexés par des numéros (en
commençant par 0)

• Chaque élément peut être identifié par sa


position.
63

Méthodes de List<E>
• E get(int i) : retourne l’élément à l’index i
• int indexOf(Object o) : indice du 1er élément égal à o (-1 sinon)
• int lastIndexOf(Object o) : dernier index de o dans la liste
• List<E> subList(int from, int to) : liste des éléments [from..to[
• ListIterator<E> listIterator() : itérateur double sens
• ListIterator<E> listIterator(int i) : itérateur initialisé à l’index i

• Optionnelles:
▫ void add(int i, E e): ajouter e à l’index i (insertion avec décalage droite)
▫ boolean addAll(int, Collection<? extend E> c) : insérer c à partir de i
▫ E remove(int i) : supprimer l’élément à l’index i (décalage gauche)
▫ E set(int i, E e): remplacer l'élément à la position i avec l'élément e

• On peut évidemment utiliser toutes les méthodes héritées de l’interface


Collection : add (E), remove(Object), …etc.
64

Itérateur pour listes :ListIterator<E>


• Cette interface définit des méthodes pour parcourir la liste dans les
deux sens et effectuer des mises à jour qui agissent sur l'élément
courant dans le parcours.

• En plus des méthodes définies dans l'interface Iterator dont elle


hérite, elle définit les méthodes suivantes :
▫ void add(E e ): ajoute e avant la position courante de l’itérateur
▫ boolean hasPrevious(): retourne true s'il reste au moins un élément à
parcourir dans la liste dans son sens inverse
▫ E previous(): renvoie l'élément précédent dans la liste
▫  void set(E e): remplace l'élément courant par celui fourni en paramètre
▫ int nextIndex(): renvoie l’index du prochain élément qui sera retourné
lors de l’appel de next.
▫  int previousIndex() : renvoie l’index du prochain élément qui sera
retourné lors de l’appel de previous.
65

Attention avec les listes d’entiers !


• Il existe 2 méthodes remove dans l’interface
List : remove(int) et remove(Object)

• Alors, que fait le code l.remove(7536) si l est


une List<Integer> ?
▫ Est-ce que l’autoboxing (boxing, unboxing
implicite) va s’appliquer ?
▫ Non, le 7537ème élément est enlevé de la liste
▫ Pour enlever l’élément 7537 de la liste d’entiers, il
faut caster explicitement le paramètre :
l.remove((Integer)7536)
66

Implémentation de List
• ArrayList<E> : C’est comme un tableau redimensionnable dont la taille
croit lorsque des éléments sont ajoutés.

• Vector<E> : Ancienne classe qui visait à disposer de tableaux


automatiquement redimensionnables (avant ArrayList)

• LinkedList<E>: Représente une liste doublement chaînée.


▫ Plusieurs méthodes pour ajouter, supprimer ou obtenir le premier ou le
dernier élément de la liste permettent d'utiliser cette classe pour gérer une
pile ou une file (addFirst(E e), addLast(E e),getFirst(), getLast(),
removeFirst(), removeLast()).

• On utilise le plus souvent ArrayList, sauf si les insertions/suppressions


au milieu de la liste sont fréquentes (LinkedList évite les décalages des
valeurs et implémente aussi l’interface Dequeue qui sera traitée plus
tard )
67

Exemple
public class Employe { public class Util{
private String leNom; public static void main(String [] args) {
private String lePrenom; ArrayList <Employe> tableauEmployes =
new ArrayList <Employe>();
private double leSalaire;
Employe emp1 = new Employe(“Hadi","Mohamed");
Employe emp2 = new Employe("Amine", "Mehdi");
public Employe (String tableauEmployes.add(emp1);
unNom, String unPrenom) { tableauEmployes.add(emp2);
leNom = unNom; //…
lePrenom = unPrenom; if (!tableauEmployes.isEmpty()) {
for (int i = 0; i<tableauEmployes.size(); i++){
}
System.out.println("Employe :"+
public String getNom() tableauEmployes.get(i).getNom());
{ }
return leNom; tableauEmployes.remove(1);
} }
} }

Résultat: Employe :Hadi


Employe :Amine
68

Exercice 1: Partie 2 - Listes


1. Créez une liste d'animaux à partir des animaux de l'ensemble de la
Partie 1 (utilisez le bon constructeur de la classe ArrayList).
2. Ajoutez plusieurs animaux ayant le même nom dans la liste, et
rajoutez plusieurs fois la même instance d'Animal. Affichez la liste.
3. Ecrivez une méthode statique prenant en paramètre une Collection
d'Animaux et qui affiche le nom de ceux dont le nom commence par
« C ». Utilisez pour cela l'littérateur fourni dans toute classe
implémentant l'interface Collection. Testez-la avec l'ensemble
d'animaux et la liste d'animaux.
4. Triez la liste d'animaux avec la méthode statique sort(List l) de la
classe Collections (avec un "s" à la fin !) et affichez-la.
69

Les Files
Interface Queue<E>
70

Interface Queue <E>


• Hérite de l’interface Collection, ajoutée par Java 1.5
• Elle représente une collection à usage général
▫ Principalement une politique type FIFO (First In, First
Out) mais d’autres politiques sont possibles (cela dépend
de l’implémentation de l’ajout des éléments)
• Le « premier » élément de la queue s’appelle la tête de
la queue
▫ C’est celui qui sera retourné/retiré en premier
• Les éléments sont ajoutés « à la queue » de la liste
▫ l’élément null est généralement interdit dans une Queue.
ÞOn ne doit pas ajouter d’éléments null
71

Méthodes de l’interface Queue <E>


• Elle contient 2 groupes de méthodes qui exécutent les
mêmes opérations de base:
▫ Un groupe, hérité de Collection, lance une exception
en cas de problème (add, remove, element)
▫ L’autre groupe renvoie une valeur particulière (false ou
null) dans les mêmes conditions (offer, poll, peek)

Lève une exception Retourne une valeur

Ajouter (enfiler un element) add(E); boolean offer(E e);

Supprimer (défiler la tête ) E remove(); E poll();

Examiner (récupère une E element(); E peek();


référence vers la tête de la
queue, sans la retirer)
72

Implémentations de Queue<E>
• LinkedList<E>, déjà vu
• PriorityQueue<E> : les éléments sont
ordonnés automatiquement
▫ L’élément récupéré en tête de queue est le plus
petit
• D’autres classes et interfaces sont liées aux
problèmes de concurrence (multi-threads)
• Pour plus de détails, consultez l’API
73

Exemple
public static void compteur(int n)
throws InterruptedException {
Queue<Integer> queue = new LinkedList<Integer>();

//Ajouter les éléments


for (int i = n; i >= 0; i--)
queue.add(i);

//Supprimer les éléments


while (!queue.isEmpty()) {
System.out.println(queue.remove());
}
}
74

Interface Deque<E>
• Sous interface de Queue<E> (ajouté au JDK 1.6)
• Représente une Queue dont les éléments peuvent être
ajoutés « aux 2 bouts » (la tête et la queue de la collection)

Lève une exception Retourne une valeur


Ajouter (enfiler un element) boolean addFirst(E e) boolean offerFirst (E e)
boolean addLast(E e) boolean offerLast (E e)
Supprimer (défiler, extraire) E removeFirst () E pollFirst ()
E removeLast () E pollLast ()
Examiner (consulter sans E getFirst () E E peekFirst ()
retirer) E getLast () E peekLast ()

• L’insertion respecte un certain ordre suivant le type de file.


75

Interface Deque<E>
• Quand une « deque » est utilisée comme une file, c’est une
file de type FIFO qui est gérée (addLast(e), offerLast(e),
removeFirst(), pollFirst(), getFirst(), peekFirst())

• Une « deque » peut être utilisée comme une Pile en utilisant


les méthodes :
▫ addFirst(e), removeFirst(), getFirst()

• Cette interface est implémentée par les classes


▫ LinkedList<E>
▫ ArrayDeque<E> (la plus utilisée) : C’est la classe conseillée
pour implémenter une pile LIFO (java.util.Stack n’est pas
conseillée pour les mêmes raisons que Vector)
76

Exemple
import java.util.*;

public class ListExample {


public static void main(String args[]) {
Deque queue = new LinkedList<String>();
queue.addFirst("Vert");
queue.addFirst("Bleu");
queue.addFirst("Rouge");
System.out.println(queue);
queue.removeFirst();
System.out.println(queue); Résultat:
queue.removeFirst(); [Rouge, Bleu, Vert]
System.out.println(queue); [Bleu, Vert]
[Vert]
}
}
77

Les Tableaux Associatifs


Map<E>
78

Problème fréquent
• Il arrive souvent en informatique d’avoir à
rechercher des informations en connaissant une
clé qui permet de les identifier
▫ Par exemple, on connaît un nom et on cherche un
numéro de téléphone
▫ ou on connaît un numéro de matricule et on cherche
les informations sur l’étudiant qui a ce matricule

=> Pour résoudre ce problème, on utilise souvent


les tableaux associatifs: Map
79

Map : tableau associatif


• L’interface Map<K,V> correspond à un groupe de couples
clé-valeur (K : type des clés, V : type des valeurs)
▫ Une clé repère une et une seule valeur
▫ Dans la map il ne peut exister 2 clés égales au sens de equals

• On peut (entre autres)


▫ ajouter et enlever des couples clé – valeur (appelée aussi
entrée)
▫ récupérer une référence à une des valeurs en donnant sa clé
▫ savoir si une table contient une valeur
▫ savoir si une table contient une clé
80

Map : Exemple
Créer un objet
Map.Entry référençant
s1 et pt1

Map<String, Point> map=


new HashMap<String,Point();
String s1=new String("Sommet A");
Point pt1=new Point (15,11);
map.put(s1,pt1);

Ranger cette
Map.Entry dans la
table à une position
qui dépend de la clé s1
81

Méthodes de Map<K,V>
• V put(K k, V v) : ajouter v avec la clé k : retourne l’ancienne valeur
associée à la clé si la clé existait déjà
• V get(Object k) : retourne la valeur associée à la clé ou null
• V remove(Object k) : supprimer l’entrée associée à k
• boolean containsKey(Object k) : retourne true si la clé k est utilisée
• boolean containsValue(Object v) : retourne true si v existe dans la
map
• void putAll(Map<? extends K,? extends V> m) : ajouter les entrées de m
• int size() : retourne le nombre d’entrées dans la table
• boolean isEmpty() : retourne true si la map est vide
• void clear() : vide la map
82

Interface interne Entry<K,V> de Map

• L’interface Map<K,V> contient l’interface


interne public Map.Entry<K,V> qui
correspond à un couple clé-valeur
• Cette interface contient 3 méthodes
▫ K getKey()
▫ V getValue()
▫ V setValue(V valeur)
• La méthode entrySet() de Map renvoie un
objet de type « ensemble (Set) de Entry »
83

Récupérer les données d’une Map


• Set<Map.Entry<K, V>> entrySet()
• Récupère les entrées (paires clé-valeur) sous forme de
Set<Map.Entry<K,V>>
• Collection<V> values()
▫ Récupère les valeurs sous forme de Collection<V>
• Set<K> keySet()
▫ Récupère les clés sous forme de Set<K>

• On utilise la méthode iterator() de l’interface Collection


adéquate (Collection ou Set) pour récupérer une à une les
valeurs
84

Parcours des Map
• Parcourir les clés de la Map
Map<Key, Value> map;
for (Key key : map.keySet()) { // manipuler key... }

• Parcourir l'ensemble des clés et des valeurs du Map


for (Key key : map.keySet()) {
Value value = map.get(key); // l'appel de get engendre un
temps coûteux en accès à chaque itération
}

Ou
for (Map.Entry<Key, Value> entry : map.entrySet())
{
Key key = entry.getKey();
Value value = entry.getValue();
// ...
}
85

Implémentations
86

Sous Interfaces
• Interface SortedMap<K,V>
▫ C’est un Map qui fournit un ordre total sur ses clés(ordre naturel
sur K ou comparateur associé à la Map)
▫ Ajoute à Map des méthodes pour extraire des sous-map, la 1ère ou la
dernière clé (semblable à SortedSet)

• Interface NavigableMap<K,V>
▫ Ajoute des fonctionnalités à un SortedMap
▫ Permet de naviguer à partir d’une de ses clés, dans l’ordre du Set ou
dans l’ordre inverse

• Lire la javadoc pour avoir les nombreuses méthodes de ces


interfaces
87

Implémentations
• HashMap<K,V>
▫ Structure de données qui permet de retrouver très rapidement un
objet si on connaît sa clé (accès en temps constant)
▫ En interne l’accès aux objets utilise un tableau et une fonction de
hachage appliquée à la clé
▫ La méthode hashCode() (héritée de Object ou redéfinie) est utilisée
comme fonction de hachage

• TreeMap<K,V>
▫ arbre ordonné suivant les valeurs des clés
▫ Implémente NavigableMap<K,V> ;
▫ La comparaison utilise l’ordre naturel (interface Comparable<?
super K>) ou une instance de Comparator<? super K> fournit
au constructeur)
88

Exercice 1: Partie 3 - Map


1. On associe à chaque animal un tatouage composé de
son nom et d'un entier unique. Ecrivez la classe
Tatouage correspondante. L'entier unique pourra être
généré via un compteur entier statique.
2. Créez une Map d'animaux contenant des animaux
indexés par leur tatouage (le choix de la classe à
utiliser vous est laissé : TreeMap, HashMap..).
3. Afficher les entrées de votre Map (utilisez la méthode
entrySet).
4. Afficher les clés et les valeurs associées de votre Map.

Vous aimerez peut-être aussi