
FAQ Langage JavaConsultez toutes les FAQ
Nombre d'auteurs : 42, nombre de questions : 297, derni�re mise � jour : 19 septembre 2017 Ajouter une question
Cette FAQ a �t� r�alis�e � partir des questions fr�quemment pos�es sur le forum Java de http://java.developpez.com ainsi que l'exp�rience personnelle des auteurs.
Nous tenons � souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose sont correctes. Les auteurs font leur maximum, mais l'erreur est humaine. Cette FAQ ne pr�tend pas non plus �tre compl�te. Si vous trouvez une erreur, ou que vous souhaitez nous aider en devenant r�dacteur, lisez ceci.
Sur ce, nous vous souhaitons une bonne lecture.
4.1. Streams (9)
- Que sont les collections ?
- Quels sont les diff�rents types d'ensembles ?
- Quels sont les diff�rents types de listes ?
- Quels sont les diff�rents types de dictionnaires ?
- Comment cr�er une collection en lecture seule ?
- Comment cr�er une collection synchronis�e ?
- Pourquoi ne faut-il pas employer la classe Vector ?
- Pourquoi ne faut-il pas employer la classe Hashtable ?
- Comment cr�er une pile (LIFO) ?
- Comment cr�er une file (FIFO) ?
- Comment trier le contenu d'une liste ?
- Comment parcourir tous les �l�ments d'un ensemble ?
- Comment convertir une liste en tableau ?
- Comment convertir un Set (ensemble) vers un tableau
- Comment convertir un tableau en liste ?
- Comment convertir un tableau vers un ensemble (Set) ?
- Comment parcourir tous les �l�ments d'un dictionnaire ?
- Comment parcourir tous les �l�ments d'une liste ?
- Comment trier un dictionnaire selon les valeurs et non pas les cl�s ?
Les collections font partie du JDK depuis la version 1.2. Les collections proposent une s�rie de classes, d'interfaces et d'impl�mentations pour g�rer efficacement les donn�es.
Pour chaque type de structure de donn�es (liste, ensemble, association), il existe une interface et plusieurs impl�mentations. Chaque impl�mentation utilise une strat�gie avec des avantages et des inconv�nients. Il est important de bien comprendre les diff�rentes strat�gies pour choisir l'impl�mentation la plus performante en fonction de ses besoins.
Conseil
Tout d'abord, afin de minimiser la quantit� de code � modifier pour changer d'impl�mentation, il convient de toujours faire r�f�rence aux collections en utilisant les interfaces, seule l'�tape de construction faisant r�f�rence � l'impl�mentation.
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 8 | // La bonne solution�: List<Object> list = new ArrayList<>(); Set<Object> set = new HashSet<>(); Map<Object> map = new TreeMap<>(); // La mauvaise solution�: ArrayList<Object> list = new ArrayList<>(); HashSet<Object> set = new HashSet<>(); TreeMap<Object> map = new TreeMap<>(); |
Il peut n�anmoins arriver qu'on soit contraint d'utiliser la 2e solution pour avoir acc�s aux m�thodes sp�cifiques � l'impl�mentation. En effet, les classes concr�tes sont souvent plus riches que les interfaces, ce qui peut se r�v�ler n�cessaire pour tirer le meilleur parti possible d'une impl�mentation.
D�tails
Les principaux types de collections sont�:
- java.util.Set - un ensemble�: un groupe d'�l�ments uniques�;
- java.util.List - une liste�: une suite d'�l�ments ordonn�s accessibles par leur indice (leur place dans la liste). Les listes ne garantissent pas l'unicit� des �l�ments�;
- java.util.Map - un dictionnaire ou une association�: ils m�morisent une collection de couples cl�-valeur. Si vous avez une cl�, l'association retrouvera la valeur associ�e � cette cl�. Les cl�s sont uniques, mais la m�me valeur peut-�tre associ�e � plusieurs cl�s.
L'API propose trois impl�mentations concr�tes pour les ensembles (java.util.Set). Un ensemble est un groupe d'�l�ments uniques.
HashSet
La classe java.util.HashSet est la plus utile des impl�mentations. L'ordre d'it�ration des �l�ments de cette collection est al�atoire.
Les op�rations add(), remove(), contains() and size() sont ex�cut�es en un temps constant.
TreeSet
La classe java.util.TreeSet contient un ensemble d'�l�ments ordonn�s�: elle impl�mente �galement l'interface java.util.SortedSet. Les �l�ments sont ordonn�s en fonction de leur ordre naturel (voir java.util.Comparable), ou en fonction d'un java.util.Comparator pr�cis� � la construction du TreeSet.
Les op�rations add(), remove(), contains() and size() sont ex�cut�es en un temps log(n).
LinkedHashSet
La classe java.util.LinkedHashSet est identique au HashSet sauf qu'elle conserve l'ordre d'insertion des �l�ments dans une liste doublement cha�n�e. L'ordre d'it�ration des �l�ments correspond � l'ordre d'insertion, l'ordre reste inchang� si l'on ajoute un �l�ment d�j� pr�sent.
Les op�rations add(), remove(), contains() and size() sont ex�cut�es en un temps constant (mais sup�rieur au temps du HashSet, car il faut �galement g�rer la liste cha�n�e).
L'API propose deux impl�mentations concr�tes pour les listes (java.util.List). Une liste est une suite ordonn�e d'�l�ments. Un �l�ment peut �tre ajout� � plusieurs endroits dans une m�me liste.
ArrayList
La classe java.util.ArrayList utilise un tableau en interne pour ranger les donn�es. Un ArrayList fournit un acc�s aux �l�ments par leur indice tr�s performant et est optimis� pour des op�rations d'ajout/suppression d'�l�ments en fin de liste.
Les donn�es de la liste sont rang�es dans un tableau d'objets. Le principal int�r�t d'un ArrayList �tant de pouvoir facilement ajouter un �l�ment � la liste, le tableau utilis� en interne est surdimensionn� par rapport au besoin. Par exemple�: un ArrayList de 5 �l�ments pourrait utiliser un tableau de 10 �l�ments, lorsqu'on ajoute un nouvel �l�ment, on le place dans la 1re case libre du tableau interne, on n'est pas oblig� d'instancier un nouveau tableau. �videmment, � force d'ajouter des �l�ments, le tableau interne peut se trouver satur�, dans ce cas un nouveau tableau est cr�� et les anciennes valeurs sont recopi�es dedans.
La gestion automatique de la taille du tableau interne ne nous emp�che pas de donner un coup de main pour am�liorer les performances. Lors de la cr�ation d'une liste, il est important d'utiliser un constructeur pr�cisant la capacit� (taille du tableau interne), il est en g�n�ral facile d'estimer la taille moyenne de sa structure de donn�es, on �vite ainsi de passer par plusieurs dizaines de r�allocations du tableau interne. De m�me, avant d'ins�rer une grande quantit� d'informations, il est possible de demander de garantir une capacit� minimale. Ces pr�cautions sont d'autant plus importantes si la liste contient beaucoup d'�l�ments.
De plus, le tableau contenu dans un ArrayList ne fait que grandir, il ne diminue jamais m�me en cas de suppression d'un ou de tous les �l�ments de la liste. Vous devez invoquer la m�thode trimToSize() de la liste pour r�duire la capacit� de stockage du tableau � la taille de la liste.
Code Java : | S�lectionner tout |
1 2 3 4 5 6 | List<String> maListe = new ArrayList<>(2); // Pr�allocation d'un tableau de capacit� 2. maListe.add("Toto"); // La capacit� du tableau ayant �t� pr�allou�e, il n'est pas redimensionn�. maListe.add("Tata"); // Idem. maListe.add("Titi"); // Augmentation de la capacit� de stockage du tableau. maListe.remove("Titi"); // La capacit� de stockage du tableau reste inchang�e. maListe.trimToSize() // R�duction de la capacit� de stockage du tableau. |
Les op�rations size(), isEmpty(), get(), set(), iterator() sont ex�cut�es en temps constant. Les op�rations d'ajout/suppression sont ex�cut�es en temps constant amorti (les ajouts/suppressions en fin de liste sont plus rapides).
LinkedList
La classe java.util.LinkedList utilise une liste cha�n�e pour ranger les donn�es. De ce fait, l'ajout et la suppression d'�l�ments sont aussi rapides quelle que soit la position, mais l'acc�s aux valeurs par leur indice est tr�s lent.
Compte tenu de son mode de stockage, la liste cha�n�e occupe, par �l�ment, un espace m�moire plus important que lorsque ce m�me �l�ment est contenu dans le tableau interne d'un ArrayList. Par contre, ici, le nombre de cellules de stockage cr��es est strictement identique � la taille de la liste, l� o� ArrayList peut manipuler un tableau plus grand que le nombre d��l�ments qu'il contient.
Code Java : | S�lectionner tout |
1 2 3 4 5 | List<String> maListe = new LinkedList<>(); maListe.add("Toto"); // Cr�ation d'une nouvelle cellule de stockage maListe.add("Tata"); // Idem. maListe.add("Titi"); // Idem. maListe.remove("Titi"); // Suppression d'une cellule de stockage. |
Les op�rations size(), isEmpty(), add, remove(), set(), get() sont ex�cut�es en temps constant. Toutes les m�thodes qui font r�f�rence � un indice sont ex�cut�es en temps O(n).
Vector
La classe java.util.Vector est une classe h�rit�e de Java 1.0. Elle n'est conserv�e dans l'API actuelle que pour des raisons de compatibilit� ascendante et elle ne devrait pas �tre utilis�e dans les nouveaux programmes. Dans tous les cas, il est pr�f�rable d'utiliser un ArrayList. Cette classe est thread-safe, c'est-�-dire que plusieurs threads (processus) peuvent l'utiliser en m�me temps sans risque.
Les donn�es d'un Vector sont rang�es dans un tableau d'objets, tout comme dans un ArrayList�; les consid�rations d�allocation de la capacit� initiale de stockage ou lors d'agrandissements de la liste sont donc identiques. La complexit� est similaire � celle de la classe ArrayList, plus le temps de synchronisation des m�thodes.
L'API propose cinq impl�mentations concr�tes pour les dictionnaires ou associations (java.util.Map). Une map permet de cr�er un ensemble de couples cl�/valeur�; on parle aussi de tableaux associatifs. La cl� permet de retrouver rapidement la valeur qui lui a �t� associ�e. Les cl�s sont des objets uniques pouvant �tre null. Les valeurs peuvent �tre multiples et null.
HashMap
La classe java.util.HashMap est l'impl�mentation concr�te la plus standard, elle est adapt�e � la plupart des situations.
Code Java : | S�lectionner tout |
1 2 3 4 5 6 | Map<Integer, String> monDictionnaire = new HashMap<>(); monDictionnaire.put(0, "Toto"); monDictionnaire.put(1, "Tata"); monDictionnaire.put(2, "Titi"); monDictionnaire.put(2, null); // �crase la valeur "Titi". String value = monDictionnaire.get(0); // Retourne "Toto". |
TreeMap
La classe java.util.TreeMap ajoute une fonction de tri des cl�s de la map. L'ordre des cl�s peut �tre choisi en donnant une instance de java.util.Comparator, sinon c'est l'ordre naturel des cl�s qui sera utilis�; elles doivent donc impl�menter java.lang.Comparable.
Code Java : | S�lectionner tout |
1 2 3 4 | Map<Integer, String> monDictionnaire = new TreeMap<>(); monDictionnaire.put(0, "Toto"); monDictionnaire.put(1, "Tata"); monDictionnaire.put(2, "Titi"); |
Si vous avez une grande quantit� de donn�es � ajouter dans la collection, et que l'ordre des cl�s n'est utile qu'apr�s l'ajout, il est plus efficace de cr�er un HashMap pour ajouter les �l�ments et de construire la TreeMap � partir de la HasMap�:
Code Java : | S�lectionner tout |
1 2 3 4 5 6 | Map<Integer, String> monDictionnaire = new HashMap<>(); // Toutes les op�rations pour ajouter les �l�ments... monDictionnaire .put(....); [...] // ... puis on construit la TreeMap. monDictionnaire = new TreeMap<>(monDictionnaire); |
LinkedHashMap
La classe java.util.LinkedHashMap conserve l'ordre d'ajout des cl�s (m�me principe qu'avec LinkedHashSet). Si la cl� ajout�e est d�j� pr�sente, l'ordre ne change pas.
IdentityHashMap
La classe java.util.IdentityHashMap, contrairement aux autres impl�mentations concr�tes, utilise l'op�rateur == pour savoir si deux cl�s sont identiques. Les autres maps utilisent le r�sultat de la m�thode equals().
WeakHashMap
La classe java.util.WeakHashMap conserve les couples en utilisant des r�f�rences faibles. Donc, si la cl� n'est plus r�f�renc�e ailleurs dans le programme, le couple est automatiquement supprim� de la collection (voir java.lang.ref.WeakReference).
Hashtable
La classe java.util.Hashtable est une classe h�rit�e de Java�1. Elle n'est conserv�e dans l'API actuelle que pour des raisons de compatibilit� ascendante et elle ne devrait pas �tre utilis�e dans les nouveaux programmes. Dans tous les cas, il est pr�f�rable d'utiliser un HashMap. Cette classe est thread-safe, c'est-�-dire que plusieurs threads (processus) peuvent l'utiliser en m�me temps sans risque.
Pour cr�er une collection en lecture seule, il suffit d'invoquer une des m�thodes unmodifiableXXX() de la classe java.util.Collections. Ces m�thodes prennent une collection (ensemble, liste, dictionnaire) en param�tre et retournent une collection du m�me type qui ne peut pas �tre modifi�e�: c'est-�-dire dont les m�thodes qui permettent de modifier le contenu (retrait, ajout, changement de valeur) de la collection l�vent une exception lorsqu'on les invoque. La nouvelle collection empaqu�te la collection d'origine�; il n'y a donc pas de duplication de donn�es ou de structure de stockage.
- unmodifiableCollection() - permet de cr�er une collection non modifiable (qui r�pond � l'interface java.util.Collection)�;
- unmodifiableList() - permet de cr�er une liste non modifiable�;
- unmodifiableMap() - permet de cr�er un dictionnaire non modifiable�;
- unmodifiableNavigableMap() - permet de cr�er un dictionnaire navigable non modifiable�;
- unmodifiableNavigableSet() - permet de cr�er un ensemble navigable non modifiable�;
- unmodifiableSet() - permet de cr�er un ensemble non modifiable�;
- unmodifiableSortedMap() - permet de cr�er un dictionnaire ordonn� non modifiable�;
- unmodifiableSortedSet() - permet de cr�er un ensemble ordonn� non modifiable.
Par exemple�:
Code Java : | S�lectionner tout |
1 2 | List<String> maListe = Arrays.asList("Toto", "Titi", "Tata"); List<String> maListeLectureSeule = Collections.unmodifiableList(maListe); |
Ici, maListeLectureSeule ne peut pas �tre modifi�e�: si vous invoquez maListeLectureSeule.add(), cette m�thode signalera une exception de type UnsupportedOperationException. La liste maListe est contenue dans maListeLectureSeule. Si des modifications (retrait, ajout, changement de valeur) sont op�r�es sur maListe, elles seront r�percut�es sur maListeLectureSeule.
Code Java : | S�lectionner tout |
1 2 3 4 | String value = maListeLectureSeule.get(0); // Ok. maListeLectureSeule.add("Tutu"); // G�n�re une exception de type UnsupportedOperationException. maListeLectureSeule.remove(1); // G�n�re une exception de type UnsupportedOperationException. maListeLectureSeule.clear(); // G�n�re une exception de type UnsupportedOperationException. |
Attention�: c'est la collection elle-m�me qui est en lecture seule, et non pas pas les �l�ments qu'elle contient. Si les �l�ments de la collection sont mutables, il est toujours possible de modifier les valeurs de ces �l�ments m�me en manipulant la collection en lecture seule.
Pour cr�er une collection synchronis�e, il suffit d'invoquer une des m�thodes synchronizedXXX() de la classe java.util.Collections. Ces m�thodes prennent une collection (ensemble, liste, dictionnaire) en param�tre et retournent une collection du m�me type dont les m�thodes sont synchronis�es�: c'est-�-dire qu'il est possible de poser des s�maphores sur ces m�thodes lors d�acc�s � la collection par des processus (threads) concurrents. La nouvelle collection empaqu�te la collection d'origine�; il n'y a donc pas de duplication de donn�es ou de structure de stockage.
- synchronizedCollection() - permet de cr�er une collection synchronis�e (qui r�pond � l'interface java.util.Collection)�;
- synchronizedList() - permet de cr�er une liste synchronis�e�;
- synchronizedMap() - permet de cr�er un dictionnaire synchronis�;
- synchronizedNavigableMap() - permet de cr�er un dictionnaire navigable synchronis�e�;
- synchronizedNavigableSet() - permet de cr�er un ensemble navigable synchronis�e�;
- synchronizedSet() - permet de cr�er un ensemble synchronis�;
- synchronizedSortedMap() - permet de cr�er un dictionnaire ordonn� synchronis�;
- synchronizedSortedSet() - Permet de cr�er un ensemble ordonn� synchronis�.
Par exemple�:
Code Java : | S�lectionner tout |
1 2 | List<String> maListe = Arrays.asList("Toto", "Titi", "Tata"); List<String> maListeSynchronisee = Collections.synchronizedList(maListe); |
Ici, maListeSynchronisee dispose d�acc�s synchronis�s sur ses m�thodes. La liste maListe est contenue dans maListeSynchronisee. Si des modifications (retrait, ajout, changement de valeur) sont op�r�es sur maListe, elles seront r�percut�es sur maListeSynchronisee. Il faut cependant �viter d'effectuer de telles modifications sur la liste source puisque cette derni�re ne dispose pas d�acc�s synchronis�s.
Les acc�s sur le contenu de la liste doivent �tre effectu�s dans des blocs synchronis�s sur la liste synchronis�e elle-m�me�:
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | // Il faut synchroniser les acc�s en lecture. synchronized (maListeSynchronisee) { String value = maListeSynchronisee.get(0); } // Et en �criture. synchronized (maListeSynchronisee) { maListeSynchronisee.add("Tutu"); } // De m�me que les it�rateurs. synchronized (maListeSynchronisee) { Iterator i = maListeSynchronisee t.iterator(); while (i.hasNext()) { faireQuelqueChose(i.next()); } } // Ou les flux. synchronized (maListeSynchronisee) { maListeSynchronisee.stream() .forEach(System.out::println); } // Ou toute op�ration qui touche au contenu de la liste. synchronized (maListeSynchronisee) { Collections.sort(maListeSynchronisee); } |
Attention�: c'est la collection elle-m�me qui est synchronis�e, et non pas les �l�ments qu'elle contient. Les acc�s aux m�thodes, getters ou setters des �l�ments de la liste ne sont pas du tout synchronis�s�!
Comme nous l'avons indiqu� plus haut, il est d�conseill� d'utiliser la classe Vector. En effet, celle-ci fait partie des vieilles classes de Java�1.0 qui datent d'avant l'ajout du framework de collections. Ses m�thodes ne respectent donc pas les standards de nommage des collections. De plus, cette classe est synchronis�e, c'est-�-dire qu'elle peut s'utiliser dans un environnement multithread� mais cela r�sulte en une perte de performances.
Il vaut donc mieux utiliser la classe ArrayList qui s'utilise presque de la m�me mani�re que Vector, mais qui n'est pas synchronis�e et fait partie des nouvelles classes du framework. Si vous avez tout de m�me besoin d'une collection synchronis�e du type de Vector, il vous suffit d'invoquer la m�thode synchronizedList() de la classe Collections�:
Code java : | S�lectionner tout |
1 2 3 | List<Voiture> listeVoiture = new ArrayList<>([...]); [...] listeVoiture = Collections.synchronizedList(listeVoiture); |
Vous aurez ainsi une List tout � fait normale mais disposant d�acc�s synchronis�s.
Comme nous l'avons indiqu� plus haut, il est d�conseill� d'utiliser la classe Hashtable. En effet, celle-ci fait partie des vieilles classes de Java�1.0 qui datent d'avant l'ajout du framework de collections. Ses m�thodes ne respectent donc pas les standards de nommage des collections. De plus, cette classe est synchronis�e, c'est-�-dire qu'elle peut s'utiliser dans un environnement multithread�, mais cela r�sulte en une perte de performances.
De plus, il n'est pas possible de stocker une valeur null dans ce type de dictionnaire�: invoquer la m�thode put() avec une valeur null g�n�rera une exception de type java.lang.NullPointerException.
Code Java : | S�lectionner tout |
1 2 3 4 5 6 | Map<String, Object> map = new Hashtable<>(); [...] map.put("toto", null); // G�n�re une NullPointerException. // Pr�f�rer�: map.remove("toto"); Object valeur = map.get("toto"); // Valeur est � null. |
Il vaut donc mieux utiliser la classe HashMap qui s'utilise presque de la m�me mani�re que Hashtable, mais qui n'est pas synchronis�e et fait partie des nouvelles classes du framework. Si vous avez tout de m�me besoin d'une collection synchronis�e du type de Hashtable, il vous suffit d'invoquer la m�thode synchronizedMap() de la classe Collections�:
Code Java : | S�lectionner tout |
1 2 3 | Map<Integer, Voiture> dictionnaireVoiture = new HashMap<>(); [...] dictionnaireVoiture = Collections.synchronizedMap(dictionnaireVoiture); |
Vous aurez ainsi une Map tout � fait normale, mais disposant d�acc�s synchronis�s.
Il existe plusieurs mani�res de cr�er une pile (LIFO ou Last In - First Out ou ��dernier entr� - premier sorti��)�:
Stack
La classe java.util.Stack pourrait correspondre � nos besoins, mais elle h�rite de Vector�; ces m�thodes sont donc synchronis�es et plus lentes que si l'on cr�ait une pile en se basant sur une collection de l'API Java�2�:
- �criture sur la pile�: push()�;
- Retrait de la pile�: pop()�;
- Lecture de la pile�: peek().
Ici, le sommet de la pile o� sont ajout�s et retir�s les �l�ments est situ� au niveau de la fin du vecteur.
Deque
L'interface java.util.Deque introduite dans le JDK�6 peut �tre utilis�e pour manipuler une pile via ses m�thodes�:
- �criture sur la pile�: addFirst() et offerFirst()�;
- Retrait de la pile�: removeFirst() et pollFirst�;
- Lecture de la pile�: peekFirst() et getFirst().
Ici, le sommet de la pile o� sont ajout�s et retir�s les �l�ments est situ� au niveau du d�but du deque.
Note�: Le mot ��deque�� (prononcer comme le mot ��deck��) est une contraction de ��double ended queue�� qui signifie ��file d'attente � double extr�mit頻.
ArrayDeque
La classe java.util.ArrayDeque introduite dans le JDK�6 est une impl�mentation concr�te de Deque qui utilise un tableau pour son stockage interne.
LinkedList
La classe java.util.LinkedList impl�mente Deque et contient donc toutes les m�thodes n�cessaires � l�utilisation d'une pile.
Cr�er sa propre classe
Le but n'est pas de r�inventer la roue, mais juste d'utiliser une classe qui porte le nom Stack ou Pile pour plus de clart� dans le code source sans plomber les performances avec la classe Stack de Java�1. L'impl�mentation propos�e ici est bas�e sur le mod�le des collections de Java�2, elle utilise une interface Stack et une classe concr�te LinkedStack.
Il existe plusieurs mani�res de cr�er une file (FIFO ou First In - First Out ou ��premier entr� - premier sorti��) �:
Queue
L'interface java.util.Queue introduite dans le JDK�5 peut �tre utilis�e pour manipuler une file via ses m�thodes�:
- �criture en fin de file�: add() et offer()�;
- Retrait en t�te de file�: remove() et poll()�;
- Lecture en t�te de file �: element() et peek().
Deque
L'interface java.util.Deque introduite dans le JDK�6 peut �tre utilis�e pour manipuler une file via ses m�thodes�:
- �criture en fin de file�: addLast() et offerLast()�;
- Retrait en t�te de file�: removeFirst() et pollFirst()�;
- Lecture en t�te de file�: getFirst() et peekFirst().
L'interface Deque �tend �galement l'interface Queue, il est donc possible d'utiliser les m�thodes d�finies dans l'interface m�re. Ici, l�avant de la file o� sont retir�s les �l�ments est situ� au niveau du d�but du deque tandis que l�arri�re de la file o� sont ajout�s les �l�ments est situ� en fin de deque.
Note�: le mot ��deque�� (prononcer comme le mot ��deck��) est une contraction de ��double ended queue�� qui signifie ��file d'attente � double extr�mit頻.
ArrayDeque
La classe java.util.ArrayDeque introduite dans le JDK�6 est une impl�mentation concr�te de Deque qui utilise un tableau pour son stockage interne.
LinkedList
La classe java.util.LinkedList impl�mente Deque et contient donc toutes les m�thodes n�cessaires � l�utilisation d'une file.
Pour trier le contenu d'une liste, il suffit d'invoquer une des variantes de la m�thode sort() de la classe utilitaire java.util.Collections�:
Code Java : | S�lectionner tout |
1 2 3 4 5 6 | List<Object> maListe = new ArrayList<>(); [...] Collections.sort(maListe); // Ou�: Comparator<Object> unComparateur = [...] // Permet de comparer les objets de la liste entre eux. Collections.sort(maListe, unComparateur); |
Le contenu de maListe est ainsi tri�e par ordre croissant. Pour trier dans l'ordre d�croissant, il suffit de faire ceci�:
Code Java : | S�lectionner tout |
Collections.sort(maListe, Collections.reverseOrder());
Attention�: pour pouvoir invoquer la variante de la m�thode sort() qui ne prend pas d'instance de Comparator en argument, il faut que les �l�ments dans la liste soient de type Comparable, tel que Integer, String, Date, etc. Prenons un exemple simple avec une classe personnalis�e�:
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | public class Voiture { String marque = ""; int nbChevaux = 0; public Voiture(String s, int i) { marque = s; nbChevaux = i; } public int getNbChevaux() { return nbChevaux; } public String toString() { return marque + "\t" + nbChevaux; } } |
On veut pouvoir trier une liste de Voiture suivant leur nombre de chevaux. Voil� alors les modifications � apporter � la classe�:
Code java : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public class Voiture implements java.lang.Comparable { [...] // m�thode � impl�menter /** * @param other Doit �tre de type Voiture�! */ public int compareTo(Object other) { int nombre1 = ((Voiture) other).getNbChevaux(); int nombre2 = this.getNbChevaux(); return nombre2 - nombre1; } } |
Maintenant, vous pouvez trier facilement une liste de voitures�:
Code java : | S�lectionner tout |
Collections.sort(listeVoiture);
Vous avez aussi la possibilit� de facilement m�langer le contenu d'une liste en invoquant la m�thode shuffle() de la classe java.util.Collections.
Il existe plusieurs mani�res de parcourir tous les �l�ments d'un ensemble�:
It�rateur
On peut parcourir une collection de type Set au moyen d'un it�rateur. Il suffira alors d'invoquer la m�thode iterator() de la collection et de le parcourir avec une boucle for traditionnelle�:
Code Java : | S�lectionner tout |
1 2 3 4 5 6 | Set<Voiture> ensembleVoiture = [...] [...] for (Iterator<Voiture> i = ensembleVoiture.iterator()�; i.hasNext()�; ) { Voiture value = i.next(); System.out.println(value); } |
Ou une boucle while�:
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 | Set<Voiture> ensembleVoiture = [...] [...] Iterator<Voiture> i = ensembleVoiture.iterator(); while (i.hasNext()) { Voiture value = i.next(); System.out.println(value); } |
Boucle for �tendue
Depuis le JDK 5.0, on peut aussi utiliser la boucle for �tendue sur la collection.
Code Java : | S�lectionner tout |
1 2 3 4 5 | Set<Voiture> ensembleVoiture = [...] [...] for (Voiture value�: ensembleVoiture) { System.out.println(value); } |
Streams
Le JDK�8 permet d'utiliser des flux sur les collections. Par exemple�:
Code Java : | S�lectionner tout |
1 2 3 4 | Set<Voiture> ensembleVoiture = [...] [...] ensembleVoiture.stream() .forEach(System.out::println); |
Il existe deux mani�res simples de convertir une liste en tableau.
List.toArray()
Cette premi�re m�thode, qui ne prend pas de param�tre, permet de convertir une liste en un tableau d'objet (Object[]).
Code Java : | S�lectionner tout |
1 2 | List<String> liste = Arrays.asList("Toto", "Tata", "Titi"); Object[] tableau = liste.toArray(); |
List.toArray(tableau)
Cette seconde m�thode prend en param�tre un tableau pr�allou� du m�me type objet (ou d'un de ses types parents) que les �l�ments contenus dans la liste. Si le tableau fourni en param�tre n'a pas la capacit� suffisante pour stocker tous les �l�ments de la liste, un nouveau tableau sera allou� et retourn� par la m�thode. Ce param�tre ne peut pas avoir la valeur null sous peine de g�n�rer une NullPointerException.
Code Java : | S�lectionner tout |
1 2 3 4 | List<String> liste = Arrays.asList("Toto", "Tata", "Titi"); String[] tableau = liste.toArray(new String[0]); // Alloue un nouveau tableau pour le r�sultat. String[] tableau = liste.toArray(new String[10]); // Conserve le tableau passe en param�tre car la capacit� est suffisante. String[] tableau = liste.toArray(null); // L�ve une exception de type NullPointerException. |
Note�: le tableau obtenu est totalement ind�pendant de la liste source et tout changement sur la liste ou le tableau ne sera pas r�percut� sur l'autre objet.
La conversion d'un ensemble (Set) vers un tableau se fait en utilisant la m�thode toArray.
Code : | S�lectionner tout |
1 2 3 4 5 | Set<String> sourceSet = new HashSet<String>(); sourceSet.add("message1"); sourceSet.add("message2"); String[] targetArray = sourceSet.toArray(new String[sourceSet.size()]); |
Les moyens les plus simples de convertir un tableau en liste sont soit de cr�er une nouvelle ArrayList � partir du tableau source, soit d'invoquer la m�thode toList() de la classe java.util.Arrays (qui effectue la m�me chose).
Code Java : | S�lectionner tout |
1 2 3 4 | String[] tableau = { "Toto", "Tata", "Titi" }; List<String> liste = new ArrayList<>(tableau); // Ou List<String> liste = Arrays.asList(tableau); // Fait exactement la m�me chose. |
Note�: initialement, le tableau source sert de tableau de stockage pour la liste�; donc tout changement dans le tableau source impacte �galement la liste. Si la capacit� de stockage de la liste change, alors le tableau de stockage de la liste sera r�allou� et deviendra donc dissoci� du tableau source.
Avertissement�: il n'est bien s�r pas possible de convertir un tableau de literals de cette mani�re.
Deux fa�ons sont disponibles pour convertir un tableau via un ensemble (Set).
Lors de la construction du Set
Code : | S�lectionner tout |
1 2 3 | String[] sourceArray = { "message1", "message2", "message3", "message4" }; Set<String> targetSet = new HashSet<String>(Arrays.asList(sourceArray)); |
En cr�ant d'abord un Set et en remplissant son contenu
Code : | S�lectionner tout |
1 2 3 4 | String[] sourceArray = { "message1", "message2", "message3", "message4" }; Set<string> targetSet = new HashSet<String>(); Collections.addAll(targetSet, sourceArray); |
Il existe plusieurs mani�res de parcourir tous les �l�ments d'un dictionnaire.
It�rateur
On peut parcourir une collection de type Map au moyen d'it�rateurs. Pour cela, il suffit de r�cup�rer soit les couples (cl�, valeur), soit les cl�s, soit les valeurs contenues dans le dictionnaire avec, respectivement, les m�thodes entrySet(), keySet() et values(). Il suffira alors d'invoquer la m�thode iterator() de la collection obtenue et de le parcourir avec une boucle for traditionnelle�:
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | Map<Integer, Voiture> dictionnaireVoiture = [...] [...] // Parcours sur les couples de la table. for (Iterator<Map.Entry<Integer, Voiture>> i = dictionnaireVoiture.entrySet().iterator()�; i.hasNext()�; ) { Map.Entry<Integer, Voiture> entry = i.next(); System.out.println(entry); } // Parcours sur les cl�s de la table. for (Iterator<Integer> i = dictionnaireVoiture.keySet().iterator()�; i.hasNext()�; ) { Integer key = i.next(); System.out.println(key); } // Parcours sur les valeurs de la table. for (Iterator<Voiture> i = dictionnaireVoiture.values().iterator()�; i.hasNext()�; ) { Voiture value = i.next(); System.out.println(value); } |
Ou une boucle while�:
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | Map<Integer, Voiture> dictionnaireVoiture = [...] [...] // Parcours sur les couples de la table. Iterator<Map.Entry<Integer, Voiture>> i = dictionnaireVoiture.entrySet().iterator(); while (i.hasNext()) { Map.Entry<Integer, Voiture> entry = i.next(); System.out.println(entry); } // Parcours sur les cl�s de la table. Iterator<Integer> i = dictionnaireVoiture.keySet().iterator(); while (i.hasNext()) { Integer key = i.next(); System.out.println(key); } // Parcours sur les valeurs de la table. Iterator<Voiture> i = dictionnaireVoiture.values().iterator(); while (i.hasNext()) { Voiture value = i.next(); System.out.println(value); } |
Il est plus efficace de boucler sur les couples contenus dans la table que de parcourir les cl�s pour ensuite retirer les valeurs�:
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 | // Mieux vaut faire�: for (Iterator<Map.Entry<Integer, Voiture>> i = dictionnaireVoiture.entrySet().iterator()�; i.hasNext()�; ) { Map.Entry<Integer, Voiture> entry = i.next(); Integer key = entry.getKey(); Voiture value = entry.getValue(); System.out.println("key = " + key + " value = " + value); } // Que�: for (Iterator<Integer> i = dictionnaireVoiture.keySet().iterator()�; i.hasNext()�; ) { Integer key = i.next(); Voiture value = dictionnaireVoiture.get(key); // Pas performant�! System.out.println("key = " + key + " value = " + value); } |
Boucle for �tendue
Depuis le JDK�5.0, on peut aussi utiliser la boucle for �tendue sur la collection listant les couples, les cl�s ou les valeurs pour parcourir une Map.
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | Map<Integer, Voiture> dictionnaireVoiture = [...] [...] // Parcours sur les couples de la table. for (Map.Entry<Integer, Voiture> entry�: dictionnaireVoiture.entrySet()) { System.out.println(entry); } // Parcours sur les cl�s de la table. for (Integer key�: dictionnaireVoiture.keySet()) { System.out.println(key); } // Parcours sur les valeurs de la table. for (Voiture value�: dictionnaireVoiture.values()) { System.out.println(value); } |
Streams
Le JDK�8 permet d'utiliser des flux sur les collections permettant d�acc�der aux couples, aux cl�s ou aux valeurs du dictionnaire. Par exemple�:
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | Map<Integer, Voiture> dictionnaireVoiture = [...] [...] // Parcours sur les couples de la table. dictionnaireVoiture.entrySet() .stream() .forEach(System.out::println); // Parcours sur les cl�s de la table. dictionnaireVoiture.keySet() .stream() .forEach(System.out::println); // Parcours sur les valeurs de la table. dictionnaireVoiture.values() .stream() .forEach(System.out::println); |
Il existe plusieurs mani�res de parcourir tous les �l�ments d'une liste�:
Boucle for ou while
Nous pouvons effectuer le parcours � l'ancienne, avec une boucle for traditionnelle, par exemple�:
Code Java : | S�lectionner tout |
1 2 3 4 5 6 | List<Voiture> listeVoiture = [...] [...] for (int index = 0�; index < listeVoiture.size()�; index++) { Voiture value = listeVoiture.get(index); // Pas performant�! System.out.println(value); } |
Ou une boucle while�:
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 | List<Voiture> listeVoiture = [...] [...] while (index < listeVoiture.size()) { Voiture value = listeVoiture.get(index); // Pas performant�! System.out.println(value); index++; } |
Cependant, dans les deux cas, le temps d'un acc�s direct � la valeur contenue dans la liste par son index d�pend fortement de l�impl�mentation sous-jacente de la liste. Il peut �tre ainsi tr�s long dans le cas d'une liste cha�n�e. On pr�f�rera passer par un it�rateur dans la mesure du possible.
It�rateur
On peut parcourir une collection de type List au moyen d'un it�rateur. Il suffira alors d'invoquer la m�thode iterator() de la collection et de le parcourir avec une boucle for traditionnelle�:
Code Java : | S�lectionner tout |
1 2 3 4 5 6 | List<Voiture> listeVoiture = [...] [...] for (Iterator<Voiture> i = listeVoiture.iterator()�; i.hasNext()�; ) { Voiture value = i.next(); System.out.println(value); } |
Ou une boucle while�:
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 | List<Voiture> listeVoiture = [...] [...] Iterator<Voiture> i = listeVoiture.iterator(); while (i.hasNext()) { Voiture value = i.next(); System.out.println(value); } |
Boucle for �tendue
Depuis le JDK�5.0, on peut aussi utiliser la boucle for �tendue sur la collection.
Code Java : | S�lectionner tout |
1 2 3 4 5 | List<Voiture> listeVoiture = [...] [...] for (Voiture value�: listeVoiture) { System.out.println(value); } |
Streams
Le JDK�8 permet d'utiliser des flux sur les collections. Par exemple�:
Code Java : | S�lectionner tout |
1 2 3 4 | List<Voiture> listeVoiture = [...] [...] listeVoiture.stream() .forEach(System.out::println); |
Dans un dictionnaire, il n'y a pas de notion d'ordre vu que l'on n'acc�de g�n�ralement pas � ses �l�ments par indice comme dans une liste, mais plut�t par des cl�s. Trier un objet de type Map suivant les valeurs revient en fait �:
- soit copier la liste des valeurs du Map dans une liste ou un tableau et trier ce conteneur. L'inconv�nient est que l'on ne travaille plus sur le dictionnaire et donc on n'a plus un acc�s direct aux �l�ments par cl�s�;
- soit r�cup�rer l'ensemble des cl�s du dictionnaire dans une liste, la trier suivant les valeurs et acc�der aux �l�ments du dictionnaire parcourant s�quentiellement les �l�ments de cette collection. Cette mani�re de faire n'est pas vraiment optimis�e compte tenu du nombre d�acc�s n�cessaires pour r�cup�rer les valeurs lors des tests�;
- ou encore r�cup�rer l'ensemble des couples du dictionnaire dans une liste, la trier suivant les valeurs et acc�der aux valeurs en parcourant s�quentiellement les couples contenus dans cette collection. L'avantage est qu'on acc�de toujours aux �l�ments directement par le couple contenu dans l'association. C'est � cette m�thode que l'on s'int�ressera.
Exemple
Consid�rons la classe suivante�:
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 8 | public class Personne { private Long id; // Identifiant d'une personne. private int age; private String nom; // Impl�menter les getters et les setters. [...] } |
Et supposons que l'on stocke un ensemble de personnes dans un Map avec l'identifiant comme cl�.
Code Java : | S�lectionner tout |
Map<Long, Personne> personnes;
Pour trier ce dictionnaire en fonction de l'�ge des personnes par exemple, on proc�de comme suit�:
- Commen�ons par cr�er un Comparator qui permet de comparer deux entr�es du dictionnaire suivant l'�ge des personnes qu'elles contiennent.
Code Java : S�lectionner tout 1
2
3
4
5
6
7
8
9
10
11
12
13public class PersonneComparator implements Comparator<Map.Entry<Long, Personne>> { public PersonneComparator() { } @Override public int compare(Map.Entry<Long, Personne> entry1, Map.Entry<Long, Personne> entry2) { Personne p1 = entry1.getValue(); Personne p2 = entry2.getValue(); // Comparer les deux couples en fonction de l'�ge des personnes contenues. return p1.getAge() - p2.getAge(); } }
- Trier les cl�s du dictionnaire en utilisant ce Comparator�:
Code Java : S�lectionner tout 1
2List<Map.Entry<Long, Personne>> entries = new ArrayList<>(personnes.entrySet()); Collections.sort(entries, new PersonneComparator());
- Acc�der aux �l�ments du dictionnaire en utilisant la liste tri�e�:
Code Java : S�lectionner tout 1
2
3
4
5for (Map.Entry<Long, Personne> entry�: entries){ Long cle = entry.getKey(); Personne personne = entry.getValue(); [...] }
Le JDK�8 permet m�me de simplifier les choses en faisant�:
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 8 | personnes.entrySet() .stream() .sorted(new PersonneComparator()) .forEach(entry -> { Long cle = entry.getKey(); Personne personne = entry.getValue(); [...] }); |
Proposer une nouvelle r�ponse sur la FAQ
Ce n'est pas l'endroit pour poser des questions, allez plut�t sur le forum de la rubrique pour �aLes sources pr�sent�es sur cette page sont libres de droits et vous pouvez les utiliser � votre convenance. Par contre, la page de pr�sentation constitue une �uvre intellectuelle prot�g�e par les droits d'auteur. Copyright � 2025 Developpez Developpez LLC. Tous droits r�serv�s Developpez LLC. Aucune reproduction, m�me partielle, ne peut �tre faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'� trois ans de prison et jusqu'� 300 000 � de dommages et int�r�ts.