• Aucun résultat trouvé

9.2 Collections et algorithmes

9.2.4 Algorithmes pour les collections

La classe Collections (notez le pluriel56) est enti`erement faite de m´ethodes statiques qui op`erent sur des

collections, pour les transformer, y effectuer des recherches, en construire de nouvelles, etc. Nous pr´esentons ici quelques m´ethodes de la classe Collections parmi les plus importantes.

A propos de relation d’ordre. Certaines des op´erations d´ecrites ci-apr`es cr´eent ou exploitent des col- lections tri´ees. Il faut savoir qu’il y a deux mani`eres de sp´ecifier la relation d’ordre par rapport `a laquelle une structure est dite tri´ee :

– L’interface Comparable. Dire d’une classe qu’elle impl´emente l’interface Comparable c’est dire que ses instances forment un ensemble muni d’une relation d’ordre, donn´ee par l’unique m´ethode de cette interface

int compareTo(Object o)

d´efinie par : a.compareTo(b) est n´egatif, nul ou positif selon que la valeur de a est inf´erieure, ´egale ou sup´erieure `a celle de b.

– L’interface Comparator. Les impl´ementations de cette interface sont des relations57qu’on passe comme

arguments aux m´ethodes qui utilisent ou cr´eent des collections ordonn´ees. Cette interface comporte essen- tiellement la m´ethode :

int compare(Object o1, Object o2)

56Il est rare qu’une classe soit d´esign´ee par un substantif pluriel ; une classe ordinaire  porte plutˆot le nom singulier qui

d´ecrit ses instances. On utilise des pluriels pour d´esigner des classes enti`erement faites d’utilitaires se rapportant `a une classe qui aurait le nom en question, au singulier. Compos´ees de variables et m´ethodes statiques, ces classes ne sont pas destin´ees `a avoir des instances, elles sont des biblioth`eques de fonctions.

57Ne pas confondre ces deux interfaces : un Comparable repr´esente un objet sur lequel est d´efinie une relation d’ordre, un

d´efinie, comme la pr´ec´edente, par : compare(a, b) est n´egatif, nul ou positif selon que la valeur de a est inf´erieure, ´egale ou sup´erieure `a celle de b.

Dans un cas comme dans l’autre, ces comparaisons supportent quelques contraintes (ce qui est dit ici sur compare s’applique ´egalement `a compareTo) :

– on doit avoir signe(compare(x,y)) == -signe(compare(y,x)) pour tout couple de valeurs x et y ; – la relation est transitive : si compare(x,y) > 0 et compare(y,z) > 0 alors compare(x,z) > 0 ; – si compare(x,y) == 0 alors signe(compare(x,z)) == signe(compare(y,z)) pour tout z ; – en outre, bien que ce ne soit pas strictement requis, on fait g´en´eralement en sorte que

(compare(x,y) == 0) == x.equals(y)

Lorsque cette derni`ere contrainte n’est pas satisfaite, la documentation doit comporter l’avertissement “Note : this comparator imposes orderings that are inconsistent with equals.”

Tri d’une collection.

static void sort(List uneListe) trie uneListe selon l’ordre naturel de ses ´el´ements, ce qui requiert que ces ´el´ements impl´ementent l’interface Comparable et soient comparables deux `a deux.

static void sort(List uneList, Comparator compar) trie uneListe selon l’ordre d´etermin´e par compar. Dans l’un et l’autre cas le tri est garanti stable : deux ´el´ements ´equivalents (pour la relation d’ordre) se retrouvent plac´es l’un par rapport `a l’autre dans la liste tri´ee comme ils ´etaient dans la liste avant le tri.

static Comparator reverseOrder() renvoie un comparateur qui repr´esente l’ordre inverse de l’ordre na- turel d’une collection. Par exemple, si l’expression Collections.sort(uneListe) est correcte, alors

Collections.sort(uneListe, Collections.reverseOrder());

est correcte aussi et produit le tri de la liste donn´ee par ordre d´ecroissant . static Object max(Collection uneCollection)

static Object max(Collection uneCollection, Comparator compar) static Object min(Collection uneCollection)

static Object min(Collection uneCollection, Comparator compar) Ces quatre m´ethodes recherchent le maximum ou le minimum d’une collection donn´ee, soit par rapport `a l’ordre naturel de la collection (dont les ´el´ements doivent alors impl´ementer l’interface Comparable) soit par rapport `a la relation d’ordre repr´esent´ee par l’argument compar.

Recherches dans une collection tri´ee

static int binarySearch(List uneListe, Object uneValeur) Recherche la valeur indiqu´ee dans la liste donn´ee en utilisant l’algorithme de la recherche binaire (ou dichotomique). La liste doit ˆetre tri´ee se- lon son ordre naturel, ce qui implique que ses ´el´ements impl´ementent l’interface Comparable et sont comparables deux `a deux.

static int binarySearch(List uneListe, Object uneValeur, Comparator compar) Recherche la va- leur indiqu´ee dans la liste donn´ee en utilisant l’algorithme de la recherche binaire (ou dichotomique). La liste doit ˆetre tri´ee selon l’ordre d´efini par compar.

Dans l’un et l’autre cas, le coˆut d’une recherche est de l’ordre de log n si la liste est bas´ee sur un vrai acc`es direct aux ´el´ements (i.e. le coˆut de la recherche est O(log n) si le coˆut d’un acc`es est O(1)). static int indexOfSubList(List grandeListe, List petiteListe) Recherche le d´ebut de la premi`ere

occurrence de petiteListe en tant que sous-liste de grandeListe. Plus pr´ecis´ement, renvoie la plus petite valeur i ≥ 0 telle que

grandeListe.subList(i, i + petiteListe.size()).equals(petiteListe) ou -1 si une telle valeur n’existe pas.

static int lastIndexOfSubList(List grandeListe, List petiteListe) Recherche le d´ebut de la derni`ere occurrence de petiteListe en tant que sous-liste de grandeListe. Plus pr´ecis´ement, renvoie la plus grande valeur i ≥ 0 telle que

grandeListe.subList(i, i + petiteListe.size()).equals(petiteListe) ou -1 si une telle valeur n’existe pas.

Pour les deux m´ethodes ci-dessus la documentation indique que la technique employ´ee est celle de la  force brute . Peut-ˆetre ne faut-il pas en attendre une grande efficacit´e...

9 QUELQUES CLASSES UTILES 9.2 Collections et algorithmes

Utilitaires de base

static List nCopies(int n, Object uneValeur) Renvoie une liste immuable form´ee de n copies de la valeur uneValeur. Il s’agit de copie superficielle : l’objet uneValeur n’est pas clon´e pour en avoir n exemplaires.

static void copy(List destin, List source) Copie les ´el´ements de la liste source dans les ´el´ements correspondants de la liste destin, qui doit ˆetre au moins aussi longue que source. Attention, cette op´eration ne cr´ee pas de structure : les deux listes doivent exister.

static void fill(List uneListe, Object uneValeur) Remplace toutes les valeurs de uneListe par l’unique valeur uneValeur.

static boolean replaceAll(List uneListe, Object ancienneValeur, Object nouvelleValeur) Remplace dans uneListe tous les ´el´ements ´egaux `a ancienneValeur par nouvelleValeur. Renvoie true si au moins un remplacement a eu lieu, false sinon.

static ArrayList list(Enumeration uneEnumeration) Construit un objet ArrayList contenant les ´el´e- ments successivement renvoy´es par l’´enum´eration indiqu´ee, plac´es dans l’ordre dans lequel cette derni`ere les a donn´es.

static void swap(List uneListe, int i, int j) ´Echange les valeurs de uneListe qui se trouvent aux emplacements i et j.

static void reverse(List uneListe) Renverse l’ordre des ´el´ements de uneListe.

static void rotate(List uneListe, int distance) Fait tourner  les ´el´ements de uneListe : l’´el´ement qui se trouvait `a l’emplacement i se trouve, apr`es l’appel de cette m´ethode, `a l’emplacement

(i + distance) modulo uneListe.size()

static void shuffle(List uneListe) R´earrange pseudo-al´eatoirement les ´el´ements de uneListe. static Set singleton(Object unObjet) Renvoie un ensemble immuable constitu´e de l’unique ´el´ement

repr´esent´e par unObjet.

static List singletonList(Object unObjet) Renvoie une liste immuable constitu´ee de l’unique ´el´ement unObjet.

static Map singletonMap(Object cl´e, Object valeur) Renvoie une liste associative immuable constitu´ee de l’unique association (cle, valeur).

La classe Collections contient encore deux autres s´eries de m´ethodes, pour lesquelles nous renvoyons `a la documentation officielle :

– des m´ethodes synchronizedCollection(Collection c), synchronizedList(List l), synchronized- Map(Map m), etc., pour obtenir une version synchronis´ee (i.e. pouvant faire face aux acc`es simultan´es faits par plusieurs thread concurrents) d’une collection donn´ee,

– des m´ethodes unmodifiableCollection unmodifiableList(List l), unmodifiableMap(Map m), etc., pour obtenir une copie immuable d’une collection donn´ee.