chapitre 11 - Collections

Transcription

chapitre 11 - Collections
Chapitre 11
Collections
(JDK 1.4)
1
Java Collections Framework: architecture
d'interfaces, de classes abstraites et de classes
concrètes permettant de stocker et manipuler
efficacement des collections d'objets.
Paquetage: java.util
- Interfaces et classes abstraites
- Classes concrètes
- Algorithmes (tri, recherche binaire)
- Arrays
- Vues
Modifications importantes avec le JDK 1.5
Ce chapitre décrit la situation avant le JDK 1.5
2
Structure générale:
- Collection
- Set
- HashSet
- SortedSet
- TreeSet
- List
- ArrayList
- LinkedList
- Map
- HashMap
- SortedMap
- TreeMap
-
On manipule des conteneurs d'objets (Object)
Pas de limitation (théorique) sur la taille du
conteneur
3
L'interface List
- Collection
- Set
- HashSet
- SortedSet
- TreeSet
- List
– ArrayList
– LinkedList
spécifie les suites d'objets, avec les méthodes
boolean add(Object o)
int indexOf(Object o)
Object get(int i)
Object set(int i, Object o)
...
4
Deux implémentations concrètes de List:
–
–
ArrayList: liste implémentée à l'aide d'un tableau
redimensionnable dont on peut fixer la capacité
initiale.
– Efficace pour get,set, add (temps « constant
amorti »)
– Coûteux d'ajouter/supprimer un élément au début
LinkedList: implémentation avec une liste
doublement chainée
– insertion/suppression d'un élément efficace
– Accès séquentiel plus coûteux (temps linéaire)
Exemple:
Point p,p1,p2,p3;
...
List l=new ArrayList();
l.add(p1);
l.add(p2);
l.add(p3);
l.add(p2);
for (int i=0;i<l.size();i++){
p=(Point) l.get(i);
// get renvoie un Object
p.affiche();
}
...
5
L'interface Set
- Collection
- Set
- HashSet
- SortedSet
- TreeSet
- List
- ArrayList
- LinkedList
Set: ensembles au sens propre, sans duplication
HashSet: implémentation avec table de hachage.
Exemple:
Point p,p1,p2,p3;
...
Set s=new HashSet();
s.add(p1);
s.add(p2);
s.add(p3);
s.add(p2);
Iterator it=s.iterator();
while(it.hasNext()){
p=(Point) it.next();
p.affiche();
}
// appelle affiche sur p1,p2,p3 (pas forcément dans cet ordre)
...
6
L'interface Collection
(pas d'implémentation directe proposée)
public interface Collection {
// Basic Operations
int size();
boolean isEmpty();
boolean contains(Object element);
boolean add(Object element); // Optional
boolean remove(Object element); // Optional
Iterator iterator();
// Bulk Operations
boolean containsAll(Collection c);
boolean addAll(Collection c); // Optional
boolean removeAll(Collection c); // Optional
boolean retainAll(Collection c); // Optional
void clear();
// Optional
// Array Operations
Object[] toArray();
Object[] toArray(Object a[]);
}
7
Itérateurs
objets permettant de parcourir une collection en
faisant abstraction de l'implémentation.
L'interface Collection propose une méthode
Iterator iterator()
qui renvoie à chaque invocation un nouvel objet
itérateur sur la collection. Cet objet est manipulé via
une référence de type Iterator:
Interface Iterator:
boolean hasNext()
Returns true if the iteration has more
elements.
Object next()
Returns the next element in the iteration.
void
remove()
Removes from the underlying collection
the last element returned by the iterator (optional
operation).
}
8
Exemple:
Point p,p1,p2,p3;
...
Collection c=new ArrayList();
l.add(p1);
l.add(p2);
l.add(p3);
l.add(p2);
...
Iterator it1=c.iterator();
p=(Point) it1.next(); // ref sur p1
...
p=(Point) it1.next(); // ref sur p2
...
p=(Point) it1.next(); // ref sur p3
it1.remove();
// élimine p3 de la liste
...
Iterator it2=c.iterator();
while (it2.hasNext()){
p=(Point) it2.next();
p.affiche();
}
...
9
-
-
l'itérateur pointe "entre" deux éléments consécutifs,
next() saute par-dessus l'élément suivant et le
renvoie.
remove() élimine l'élément traversé par le dernier
next().
Attention:
i.next();
i.next();
i.remove();
i.remove(); // impossible
–
–
L'ordre de parcours dépend du type de collection:
– séquentiel pour les listes
– indéterminé pour HashSet
– ordre naturel des éléments pour TreeSet
Le comportement d'un itérateur est indéterminé si
l'on essaie de modifier la collection autrement
qu'avec remove.
Exemple: implémentation de ListIterator dans
LinkedList: levée d'une exception
ConcurrentModificationException
10
Autre exemple:
class Utilitaire{
...
public static void AfficheCollection(Collection c){
Iterator it=c.iterator();
while (it.hasNext())
System.out.println(it.next());
}
...
}
Remarque: on pourrait aussi concevoir une méthode
public static void AfficheCollection(Iterator it)
D'autres itérateurs:
- itérateur bi-directionnel (interface ListIterator pour
LinkedList)
-
on peut concevoir ses propres itérateurs, exemples:
itérateurs "circulaires", ou filtrants (classes
internes)
Ancêtre d'Iterator:
Interface Enumeration
boolean hasMoreElements()
Object nextElement();
11
Comparaison d'objets
Interface Comparable
int compareTo(Object o)
Compares this object with the specified object for order.
Permet de définir une relation d'ordre totale entre les
objets d'une classe.
Si < relation d'ordre totale, alors a.compareTo(b)
renvoie une valeur
– strictement négative si a<b
– 0 si a=b
– strictement positive si a>b
Quelques classes qui implémentent Comparable:
Character, File, Long, Short, String, Float, Integer,
Byte, Double, BigInteger, BigDecimal, Date...
Relation d'ordre « naturelle », utilisée par défaut
– par les méthodes de tri de tableaux/listes d'objets
– par les collections ordonnées
12
Une méthode de la classe Arrays.java (du package
java.util):
private static void mergeSort(Object src[], Object dest[],
int low, int high) {
int length = high - low;
// Insertion sort on smallest arrays
if (length < 7) {
for (int i=low; i<high; i++)
for (int j=i; j>low &&
((Comparable)dest[j-1]).compareTo((Comparable)dest[j])>0; j--)
swap(dest, j, j-1);
return;
}
// Recursively sort halves of dest into src
int mid = (low + high)/2;
mergeSort(dest, src, low, mid);
mergeSort(dest, src, mid, high);
// If list is already sorted, just copy from src to dest. This is an
// optimization that results in faster sorts for nearly ordered lists.
if (((Comparable)src[mid-1]).compareTo((Comparable)src[mid]) <= 0)
{
System.arraycopy(src, low, dest, low, length);
return;
}
// Merge sorted halves (now in src) into dest
for(int i = low, p = low, q = mid; i < high; i++) {
if (q>=high || p<mid && ((Comparable)src[p]).compareTo(src[q])
<=0)
dest[i] = src[p++];
else
dest[i] = src[q++];
}
}
13
Collections ordonnées
SortedSet: sous-interface de Set pour les ensembles
ordonnés
Quelques méthodes:
first()
last()
subset(Object initial,Object final)
iterator() (parcourt l'ensemble dans l'ordre)
L'ordre est soit l'ordre naturel, soit celui fourni à la
construction par un objet Comparator (cf plus loin)
Remarque: subset renvoie une vue adossée au Set
TreeSet: implémentation de SortedSet avec un arbre
équilibré.
Parmi les constructeurs:
TreeSet()
Constructs a new, empty set, sorted according to the
elements' natural order.
TreeSet(Comparator c)
Constructs a new, empty set, sorted according to the given
comparator.
14
Exemple:
import java.util.*;
class TestSortedSet{
public static void main(String[] args){
SortedSet s=new TreeSet();
s.add("aaa");
s.add("ccc");
s.add("aaaa");
s.add("baaa");
s.add("aaab");
s.add("bbb");
for (Iterator it=s.iterator();it.hasNext();)
System.out.println(it.next());
}
}
// affiche aaa,aaaa,aaab,baaa,bbb,ccc
15
Implémenter Comparable
class Point implements Comparable{
...
public boolean equals(Object o){
if (this==o) return true;
if (o==null) return false;
if (getClass( ) != o.getClass( )) return false;
Point p=(Point)o;
return ((this.x==p.x)&&(this.y==p.y));
}
public int compareTo(Object o){
if (!(o instanceof Point))
throw new ClassCastException();
Point q=(Point)o;
if (this.equals(q))
return 0;
if ((this.x<q.x)||((this.x==q.x)&&(this.y<q.y)))
return -1;
return 1;
}
16
L'interface Comparator
Si la solution précédente ne convient pas:
Interface Comparator (java.util)
int compare(Object o1, Object o2)
Compares its two arguments for order.
Exemple:
– on déclare une classe PointComparator qui
implémente Comparator et définit la relation
d'ordre qui nous intéresse.
– On récupère une référence c sur une instance de
cette classe.
– On passe c comme argument aux méthodes le
permettant. Ces méthodes s'adresseront à c
lorsqu'elles auront besoin d'effectuer des
comparaisons de deux points.
17
Exemples:
–
Dans java.util.Collections:
static void sort(List list)
Sorts the specified list into ascending order,
according to the natural ordering of its
elements.
static void sort(List list, Comparator c)
Sorts the specified list according to the order
induced by the specified comparator.
–
Dans les collections ordonnées:
TreeSet()
Constructs a new, empty set, sorted according to
the elements' natural order.
TreeSet(Comparator c)
Constructs a new, empty set, sorted according to
the given comparator.
18
Exemple:
import java.util.*;
class PointComparator implements Comparator{
public int compare(Object o1,Object o2){
if (!((o1 instanceof Point)&&(o2 instanceof Point)))
throw new ClassCastException();
Point p1=(Point)o1;
Point p2=(Point)o2;
if (p1.equals(p2))
return 0;
if ((p1.getY()<p2.getY())||((p1.getY()==p2.getY())&&
(p1.getX()<p2.getX())))
return -1;
return 1;
}
}
// utiliser plutôt le pattern Singleton
public class TestComparator{
public static void main(String[] args){
Comparator c=new PointComparator();
SortedSet s=new TreeSet(c);
s.add(new Point(1,2));
s.add(new Point(0,3));
s.add(new Point(5,0));
for (Iterator it=s.iterator();it.hasNext();)
System.out.println(it.next());
}
}
// l'ordre sera ici: (5,0),(1,2),(0,3)
19
L'interface Map
- Map
- HashMap
- SortedMap
– TreeMap
Ne dérive pas de Collection.
Map: « application » (table, tableau associatif)
– une Map consiste en un ensemble de couples
(clé,valeur)
- chaque clé n'apparaît pas plus d'une fois (une valeur
peut apparaître plusieurs fois)
– utile pour trouver rapidement la valeur associée à
une clé.
Clés et valeurs sont des Object.
Un couple (clé,valeur) est un Map.Entry
Méthodes:
Object put(Object key,Object value) renvoie l'objet
précédemment associé à la clé ou null
boolean containsKey(Object key)
Object get(Object key)
Object remove(Object key) supprime l'association de
clé et renvoie l'objet associé ou null.
20
HashMap: implémente Map avec une table de
hachage.
– get, put en temps constant
Exemple: stocker des couples (login,mot de passe)
import java.util.*;
class TestMap {
public static void main(String[] args){
Map m=new HashMap();
m.put("user1","1234");
System.out.println(m.get("user1"));
m.put("user2","medor");
m.put("user1","fifi");
System.out.println(m.containsKey("user2"));
System.out.println(m.get("user1"));
}
}
SortedMap: sous-interface de Map pour le cas où
l'ensemble des clés est ordonné
TreeMap: implémente SortedMap à l'aide
d'arbres rouge/noir de sorte que les opérations
containsKey, get, put, remove se font en temps
O(log n)
21
Maps et Collections
On peut obtenir des vues sur un objet Map
Set keySet()
renvoie l'ensemble des clés (sur lequel on peut ensuite itérer)
Collection values()
renvoie la collection des valeurs associées aux clés
Set entrySet()
renvoie l'ensemble des "entrées", i.e des couples (clé, valeur).
Les « entrées » sont des instances d'une classe
qui implémente l'interface Map.Entry
Interface Map.Entry:
Object getKey()
Object getValue()
Object setValue(Object value)
22
La classe Collections
consiste uniquement en des methodes static qui
agissent sur et renvoient des collections:
Algorithmes:
- min,max
static Object min(Collection coll)
static Object min(Collection coll, Comparator comp)
- sort (tri fusion)
- binarysearch (dans les listes ordonnées)
- copy
– shuffle
Wrappers:
méthodes qui renvoient des vues adossées à des
collections:
– vues synchronisées
– vues immutables:
static Collection unmodifiableCollection(Collection c)
static List unmodifiableList(List list)
static Map unmodifiableMap(Map m)
static Set unmodifiableSet(Set s)
static SortedMap unmodifiableSortedMap(SortedMap m)
static SortedSet unmodifiableSortedSet(SortedSet s)
23
la classe Arrays
Boîte à outils pour manipuler les tableaux.
Méthodes (beaucoup de surcharges):
– binarysearch
– equals
– fill
– sort (quicksort)
Exemples:
static void
sort(Object[] a)
Sorts the specified array of objects into ascending order,
according to the natural ordering of its elements.
static void
sort(Object[] a, Comparator c)
Sorts the specified array of objects according to the order
induced by the specified comparator.
24
Utiliser les classes de collections
–
–
–
–
Les classes existantes remplacent souvent très
avantageusement les tableaux.
Les classes manipulent des collections d'Object.
Conséquences:
Pas de contrôle de type (penser notamment à
equals, clone...)
On doit donc souvent utiliser le transtypage
Liste l=new ArrayList();
...
Point p=(Point) l.get(i);
...
- Problème: les types primitifs ne sont pas des
classes.
25
Classes enveloppes pour les types primitifs
Classes qui permettent d'intégrer les types primitifs
aux classes
A chaque type primitif est associée une classe
"enveloppe" dans java.lang: Integer, Double...
Cette classe est immutable.
Méthodes:
- constructeur à un argument (du type associé)
- emballage/déballage
Exemple:
int i=4;
Integer envi=new Integer(i);
int j=envi.intValue();
// emballage
// déballage
Types primitifs et collections:
List l=new ArrayList();
l.add(new Integer(13));
...
int i=((Integer) l.get(0)).intValue();
JDK 1.5: emballage et déballage implicites
26
Compléments
Concevoir ses propres classes de collections
Utiliser les squelettes d'implémentation
Dans l'architecture sont incluses des classes abstraites
qui fournissent un squelette d'implémentation qui
facilite la conception de nouvelles classes.
(source: http://www.liafa.jussieu.fr/~carton/)
27
Exemple:
public abstract class AbstractCollection
extends Object
implements Collection
This class provides a skeletal implementation of the Collection interface, to
minimize the effort required to implement this interface.
To implement an unmodifiable collection, the programmer needs only to extend this class
and provide implementations for the iterator and size methods. (The iterator
returned by the iterator method must implement hasNext and next.)
To implement a modifiable collection, the programmer must additionally override this
class's add method (which otherwise throws an
UnsupportedOperationException), and the iterator returned by the iterator
method must additionally implement its remove method.
The programmer should generally provide a void (no argument) and Collection
constructor, as per the recommendation in the Collection interface specification.
The documentation for each non-abstract methods in this class describes its
implementation in detail. Each of these methods may be overridden if the collection being
implemented admits a more efficient implementation.
Il peut être nécessaire de redéfinir certaines des
méthodes par souci d'optimisation.
28
Respecter le contrat des interfaces implémentées
Exemple (Collection):
« All general-purpose Collection implementation classes (which
typically implement Collection indirectly through one of its
subinterfaces) should provide two "standard" constructors: a void (no
arguments) constructor, which creates an empty collection, and a
constructor with a single argument of type Collection, which
creates a new collection with the same elements as its argument. In
effect, the latter constructor allows the user to copy any collection,
producing an equivalent collection of the desired implementation
type. There is no way to enforce this convention (as interfaces cannot
contain constructors) but all of the general-purpose Collection
implementations in the SDK comply. »
Cas des classes immutables
Pour simplifier l'architecture, les interfaces proposent
plusieurs méthodes optionelles, dont les mutateurs
Exemple (Collection):
boolean add(Object o)
Ensures that this collection contains the
specified element (optional operation)
Il faut donc implémenter ces méthodes en levant si
nécessaire une exception
UnsupportedOperationException
(remarque: penser aux vues)
29

Documents pareils

•Collection Collection (conteneur) est un objet qui regroupe

•Collection Collection (conteneur) est un objet qui regroupe Un itérateur permet de parcourir une collection La notion d’itérateur est implantée en Java par l’interface Iterator public boolean hasNext() public Object next() public void remove() (enlève le de...

Plus en détail