Les FAQs Java :
FAQ JAVA FAQ Java EE FAQ Java ME FAQ Java XML FAQ JavaFX FAQ Java GUI FAQ Struts FAQ JSF FAQ JDBC JDO FAQ Hibernate FAQ Spring FAQ Eclipse FAQ NetBeans FAQ JCreator FAQ Maven 2

FAQ JavaConsultez toutes les FAQ

Nombre d'auteurs : 53, nombre de questions : 231, dernière mise à jour : 26 janvier 2014 

 
OuvrirSommaireGénéralitésStructures de données -Tableaux et collections

Les collections font partie de Java (J2SE) 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) 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.

 
Sélectionnez
// La bonne solution : 
List<Object> list = new ArrayList<Object>();
Set<Object> set = new HashSet<Object>();
Map<Object> map = new TreeMap<Object>();
// La mauvaise solution : 
ArrayList<Object> list = new ArrayList<Object>();
HashSet<Object> set = new HashSet<Object>();
TreeMap<Object> map = new TreeMap<Object>();

Il peut néanmoins arriver qu'on soit contraint d'utiliser la 2ème 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 java.util.Set (ensembles) sont un groupe d'éléments uniques.
Les java.util.List (listes) sont 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.
Les java.util.Map (associations) 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.

Mis à jour le 20 décembre 2009  par Clément Cunin, Baptiste Wicht

Lien : Quel différence entre HashSet, TreeSet et LinkedHashSet ?
Lien : Quelles différences entre ArrayList, LinkedList et Vector ?
Lien : Quels sont les différents types de Map ?

L'API propose trois implémentations concrètes pour les ensembles (java.util.Set). Un ensemble est un groupe d'élément uniques.

java.util.HashSet :
Le java.util.HashSet est la plus utile des implémentations.
Note : L'ordre d'itération des éléments est aléatoire.
Complexité : Les opérations add, remove, contains and size sont exécutées en un temps constant.

java.util.TreeSet :
Le java.util.TreeSet contient un ensemble d'éléments ordonnés (il 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.
Complexité : Les opérations add, remove, contains and size sont exécutées en un temps log(n).

java.util.LinkedHashSet :
Un java.util.LinkedHashSet est identique au HashSet sauf qu'il conserve l'ordre d'insertion des éléments dans une liste doublement chainée.
Note : 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.
Complexité : 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 chainée).

Créé le 1er janvier 2004  par Clément Cunin

Lien : Comment bien utiliser les collections ?

L'API propose deux implémentations concrètes pour les listes (java.util.List). Une liste est une suite ordonnée d'éléments (les éléments peuvent être ajoutés à plusieurs endroits de la liste).

java.util.ArrayList :
Un 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.
Complexité : 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).

java.util.LinkedList :
Un java.util.LinkedList utilise une liste chainée pour ranger les données. L'ajout et la suppression d'éléments est aussi rapide quelle que soit la position, mais l'accès aux valeurs par leur indice est très lente.
Complexité : 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).

java.util.Vector :
La classe java.util.Vector est une classe héritée de Java 1. Elle n'est conservée dans l'API actuelle que pour des raisons de compatiblité 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.
Note : Cette classe est "thread-safe", c'est-à-dire que plusieurs processus peuvent l'utiliser en même temps sans risque.
Complexité : idem que pour ArrayList, plus le temps de synchronisation des méthodes.

Mis à jour le 3 avril 2005  par Clément Cunin

Lien : Comment bien utiliser les collections ?

L'API propose cinq implémentations concrètes pour les 'Map' (java.util.Map). Une map permet de créer un ensemble de couples clé/valeur (On parle aussi de tableaux associatifs), la clé permettant 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.

java.util.HashMap :
La classe java.util.HashMap est l'implémentation concrète la plus standard, elle est adaptée à la plupart des situations.

java.util.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). Si vous avez une grande quantité de données à ajouter dans la collection et que l'ordre 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 :

 
Sélectionnez

Map<Object> map = new HashMap<Object>();
// Toutes les operations pour ajouter les éléments... 
map.put(....);
 
// ... puis on construit la TreeMap. 
map = new TreeMap<Object>(map);

java.util.LinkedHashMap :
La classe java.util.LinkedHashMap conserve l'ordre d'ajout des clés (même principe que java.util.LinkedHashSet avec un set). Si la clé ajoutée est déjà présente, l'ordre ne change pas.

java.util.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 utilisent le résultat de la méthode equals(java.lang.Object)).

java.util.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).

java.util.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 compatiblité 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.

Mis à jour le 20 décembre 2009  par Clément Cunin, Baptiste Wicht

Lien : Comment bien utiliser les collections ?

La classe Stack
La classe java.util.Stack pourrait correspondre à nos besoins, mais elle hérite de Vector, ces méthodes sont synchronisées et donc plus lentes que si l'on créait une pile en se basant sur une collection de l'API java 2 ( voir : Comment bien utiliser les collections ?).

La classe LinkedList
La classe java.util.LinkedList contient toutes les méthodes nécessaires à la création d'un pile : addFirst(Object o), getFirst() et removeFirst(). On peut donc très bien utiliser cette classe comme 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 Java2, elle utilise une interface Stack et une classe concrète LinkedStack.

Créé le 1er janvier 2004  par Clément Cunin

Lien : Comment bien utiliser les collections ?
Téléchargement : Stack.java
Téléchargement : LinkedStack.java

La taille d'un tableau est fixée lors de sa construction et ne peut plus être modifiée. La seule solution consiste à créer un nouveau tableau plus grand et à copier les anciennes valeurs dans le nouveau tableau. Pour effectuer la copie de tableau, on utilise la méthode arraycopy(java.lang.Object, int, java.lang.Object, int, int) de la classe java.lang.System bien plus performante qu'une itération.

 
Sélectionnez

/** la méthode simple */
int[] nouveau = new int[longueur];
System.arraycopy(vieuxTableau,0,nouveau,0,vieuxTableau.length);
/** Note : On place ici les anciennes valeurs au début du nouveau tableau. */

Note :
La création d'un nouveau tableau est une opération coûteuse en terme de performances, si vous devez utiliser une structure de données dont la taille change souvent, il est fortement conseillé d'utiliser une liste (Quelles différences entre ArrayList, LinkedList et Vector ?).

Créé le 1er janvier 2004  par Clément Cunin

Lien : Quelles différences entre ArrayList, LinkedList et Vector ?

Bien utiliser une structure de données implique d'en comprendre le fonctionnement. Les classes java.util.Vector et java.util.ArrayList fonctionnent de la même manière (Quel différence ?).

Structure interne :
Les données de la liste sont rangées dans un tableau d'objets. Le principal intérêt d'un ArrayList ou d'un Vector étant de pouvoir facilement ajouter un élément à la liste, le tableau utilisé en interne est surdimensionné par rapport au besoin. Exemple : Un ArrayList de 5 éléments pourrait utiliser un tableau de 10 éléments, lorsque qu'on ajoute un nouvel élément, on le place dans la 1ère case libre du tableau interne, on n'est pas obligé d'instancier un nouveau tableau. Evidemment, à 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.

Optimisation :
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éallocation du tableau interne. De même, avant d'insérer une grande quantité d'information, 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.

Mis à jour le 20 décembre 2009  par Clément Cunin

Lien : Comment bien utiliser les collections ?
Lien : Quelles différences entre ArrayList, LinkedList et Vector ?

La classe java.util.Collections apporte la solution :

 
Sélectionnez
List<Object> ma_liste = new ArrayList<Object>();
Collections.sort(ma_liste);

ma_liste est ainsi triée par ordre croissant. Pour trier dans l'ordre décroissant, il suffit de faire ceci :

 
Sélectionnez
Collections.sort(ma_liste, Collections.reverseOrder()); 

Attention cependant, cet exemple fonctionne que si les éléments dans la liste sont de type Comparable, comme int, String, Date, ... (voir l'interface java.lang.Comparable). Si ce n'est pas le cas (les éléments sont des objets que vous avez défini), il faut que votre classe implémente l'interface java.lang.Comparable, donc en fait il faut définir la méthode int compareTo(Object o). Prenons un exemple simple :

 
Sélectionnez
class Voiture { 
    String marque = ""; 
    int nbCheveau = 0; 
 
    public Voiture(String s, int i) { 
        marque = s; 
        nbCheveau = i; 
    } 
 
    public int getNbCheveau()  { return nbCheveau;  }
 
    public String toString()  { return marque + "\t" + nbCheveau;   }
}

On veut pouvoir trier une liste de Voiture suivant leur nombre de chevaux. Voilà alors les modifications à apporter à la classe :

 
Sélectionnez

 
class Voiture implements java.lang.Comparable { 
   // méthode à implémenter
   /**
     * @param other other doit être de type Voiture !
     */
   public int compareTo(Object other) { 
      int nombre1 = ((Voiture) other).getNbCheveau(); 
      int nombre2 = this.getNbCheveau(); 
      if (nombre1 > nombre2)  return -1; 
      else if(nombre1 == nombre2) return 0; 
      else return 1; 
   } 
} 

Maintenant, vous pouvez trier facilement une liste de voitures :

 
Sélectionnez
Collections.sort(liste_voitures);

Le code est identique pour un tableau. Il faut seulement utiliser la classe Arrays.

 
Sélectionnez
Arrays.sort(unTableauDeVoitures);

Vous avez aussi la possibilité de facilement mélanger une liste grâce à la méthode shuffle de Collections.

Mis à jour le 20 décembre 2009  par braim, duj, Grégory Danelon

Lien : Comment bien utiliser les collections ?
Lien : Quelles différences entre ArrayList, LinkedList et Vector ?

Tout simplement en faisant :

 
Sélectionnez
boolean estUnTableau = monObjet.getClass().isArray();
Créé le 1er mars 2003  par Clément Cunin

Cette propriété n'est pas directement accessible, mais une petite fonction permet de la calculer rapidement. On se base sur le fait qu'un tableau à plusieurs dimensions est en fait un tableau de tableaux.

 
Sélectionnez

 
public static int getNbDimension( Object monTableau ) {
        int dim=0;
        Class cls = monTableau.getClass();
        while( cls.isArray() ) {
                cls = cls.getComponentType();
                dim++;
        } 
        return( dim );
} 
Créé le 1er mars 2003  par Clément Cunin

Pour instancier un tableau, il faut :

  • Réserver la place en mémoire pour les N références vers les objets du tableau,
  • Réserver la place pour chaque objet, car la création d'un tableau d'objets, va créer un tableau rempli de null

Par exemple :

 
Sélectionnez

Point[] p = new Point[10];       // réserver la place en mémoire pour 10 références vers des objets Point
for(int i=0 ; i<p.length ; i++) { 
	p[i] = new Point(i, i+10);      // réserve en mémoire la place pour un objet point (10 fois) 
}

Si l'on essaye d'instancier des tableaux d'objets sans réserver la place de chaque objets en mémoire, on reçoit une exception «NullPointerException » lors de l'accès à l'objet. Comme par exemple en créant un tableau de Point comme on créerais un tableau d'int.

Alors qu'avec un tableau de types primitifs, chaque "case" du tableau est directement rempli avec la valeur par défaut de celui-ci, car un type primitif ne peut pas être null.

Créé le 25 mars 2007  par vasilov

Lien : Comment agrandir un tableau ?

En Java, les tableaux ne sont pas extensibles. On doit donc procéder en 2 étapes, créer un nouveau tableau plus grand, puis copier toutes les valeurs de l'ancien tableau dans le nouveau.

 
Sélectionnez

Object nouveauTableau = Array.newInstance( ancienTableau.getClass().getComponentType(), 
                                                                         nouvelleTaille );
System.arraycopy( ancienTableau, 0, nouveauTableau, Array.getLength(ancienTableau);

Note :
Avant de vous embarquer dans cette solution, réfléchissez bien si un .ArrayList ou un Vector ne seraient pas plus appropriés à votre problème.

Créé le 1er mars 2003  par Clément Cunin

Boucle "for"

A l'ancienne, avec une boucle for traditionnelle

 
Sélectionnez
int tab[50];
...
for (int index = 0; index < tab.length; index++)
   System.out.println(tab[index]);

Boucle "for each"

Le JDK 5.0 apporte une construction de boucle performante qui permet de parcourir tous les éléments d'un tableau, ou d'un objet implémentant l'interface Iterable (ArrayList, ...), sans se préoccuper de l'indice.

 
Sélectionnez
int tab[50];
...
for (int n : tab)
   System.out.println(n);
Mis à jour le 21 octobre 2007  par Nourdine Falola


Les Generics introduits dans Java 5.0 permettent une compatibilité avec les anciennes librairies qui utiliserait leurs équivalent non paramétrés. Ainsi s'il est possible d'affecter une référence non-paramétré dans son homologue paramétré, par exemple :

 
Sélectionnez

Map<String,String[]> parameters = request.getParameterMap(); // retourne une Map


Malheureusement, ce code génère un warning car il n'est pas sécurisé :

 
Sélectionnez

warning: [unchecked] unchecked conversion


En effet il est impossible pour le compilateur de vérifier que l'objet non-paramétré respectent les conditions de la déclaration en Generics. Ainsi dans notre exemple la Map retourné par getParameterMap() pourrait très bien contenir des objets de type différents sans que le compilateur ne puisse le détecter, ce qui provoquerait des exceptions inattendus lors de l'utilisation de la variable parameters.


Toutefois, ce type d'affectation peut s'avérer utile afin d'utiliser conjointement des API Generics avec d'autres qui ne le sont pas, surtout que dans cet exemple la documentation de la méthode précise bien que la Map renvoyé respecte bien la déclaration Map<String,String[]>.


On peut ainsi utiliser l'annotation @SuppressWarning pour indiquer au compilateur que l'on prend en charge la sécurité de ce code :

 
Sélectionnez

@SuppressWarnings("unchecked")
Map<String,String[]> parameters = request.getParameterMap();


L'annotation @SuppressWarning ne pouvant pas s'appliquer à une seule instruction en dehors des déclarations de variable, on peut utiliser la méthode suivante afin de limiter son scope d'utilisation :

 
Sélectionnez

	/**
	 * Cast non sécurisé.<br/>
	 * Cette méthode permet de caster des types non-paramétré en
	 * type paramétré.<br/>
	 * Exemple :
	 * {@code List<String> list = uncheckedCast( maListeNonParamétré ); }
	 * <br/>
	 * <b>Attention :</b> cela peut avoir des effets de bords
	 * indésirables si la référence en paramètre ne respectent
	 * pas le type paramétré !
	 * 
	 * @param <P> Type du paramètre de la méthode.
	 * @param <R> Type de la valeur de retour.
	 * @param p Paramètre à "caster".
	 * @return La référence 'p', castée dans le type de R.
	 * @throws ClassCastException en cas de type incompatible.
	 */
	@SuppressWarnings("unchecked")
	public static <P,R extends P> R uncheckedCast(P p) throws ClassCastException {
		return (R) p;
	}
 
Sélectionnez

Map<String,String[]> parameters = null;
parameters = uncheckedCast(request.getParameterMap());

Cette méthode est très proche d'un cast standard et permet les mêmes vérifications.

Quelques exemples :

 
Sélectionnez

Object reference = new ArrayList();
Map<String,String> map = uncheckedCast(reference); // ClassCastException

Ce code compilera sans erreur (car une référence de type Object pourrais contenir une Map), mais génèrera une exception à l'exécution (puisqu'en réalité il contient un type incompatible avec Map).

 
Sélectionnez

ArrayList reference = new ArrayList();
Map<String,String> map = uncheckedCast(reference); // Erreur

A l'inverse, ce code provoquera une erreur car le compilateur détectera que la type de la référence est incompatible avec le type attendu.

Attention : La sécurité du code et de la correspondance entre le type standard et la déclaration utilisant les Generics est entièrement à la charge du développeur. Une mauvaise utilisation pourrait provoquer des erreurs d'exécutions plus loin dans le code.

Mis à jour le 21 octobre 2007  par adiGuba

Lien : [Java 5.0] Comment supprimer un warning en particulier ?


Le compilateur interdit toute création de tableau de type paramétré, ainsi la ligne suivante provoquera irrémédiablement une erreur :

 
Sélectionnez

List<String> stringListArray[] = new List<String>[100];


Ce problème vient du fait que les tableaux et les Generics ont une approche totalement opposée de la vérifications des types.


Avec les tableaux, la quasi-totalité des vérifications est effectué pendant l'exécution, et la plupart des opérations sur les tableaux peuvent générer des ClassCastException selon le type réel du tableau et le type réel de l'élément qu'on lui affecte.


A l'inverse, les Generics sont sécurisé à la compilation. C'est à dire que c'est le compilateur qui se charge de vérifier la cohérence de l'ensemble pendant la compilation, et qui garantit l'absence d'exception pendant l'exécution.


Du fait de leurs fortes oppositions et de l'héritage particulier des tableaux, l'utilisation de tableaux Generics peut aboutir à des situations complètement fausses et générer des exceptions inattendus.


Ainsi, si la création de tableaux Generics étaient possible, il serait relativement simple de passer outre la protection des Generics sans warnings ni erreurs :

 
Sélectionnez

List<String>[] stringListArray = new List<String>[100]; // ERREUR
 
Object[] simpleArray = stringListArray;
 
simpleArray[0] = new ArrayList<Number>(); // OK ?!?!?


Le pire c'est que ce code ne génèrerait même pas d'exception lors de son exécution. Au contraire l'exécution serait reporté lors de l'utilisation des données du tableaux alors qu'il devrait s'agir d'un code sécurisé...


Bref, l'utilisation de tableaux Generics est loin d'assurer la sécurité de code promise par les Generics, et le compilateur interdit donc leurs créations.


Il existe pourtant deux alternatives.


La meilleur solution serait d'utiliser l'API de Collection, et donc une List à la place du tableau. En effet dans ce cas le cas de figure décris ci-dessus, l'utilisation des Generics permettrait d'être avertit du problème via un warning :

 
Sélectionnez

List<List<String>> stringListList = new ArrayList<List<String>>();
 
List simpleList = stringListList;
 
simpleList.add( new ArrayList<Number>() ); // Warning unchecked


La seconde solution, à n'utiliser que si l'utilisation du tableau est vraiment une nécessité, consiste à créer un tableau non-Generics et à ignorer le warning reçu :

 
Sélectionnez

@SuppressWarnings("unchecked")
List<String>[] stringListArray = new List[100];


Mais bien entendu cela ne corrige en rien le problème des tableaux Generics...

Créé le 25 août 2007  par adiGuba

Lien : Comment caster un type non-paramétré vers son équivalent paramétré ?


Dans un Map, il n'y 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 clés.


Trier un Map suivant les valeurs revient en fait à :

  • Soit copier la liste des valeurs du Map dans une Liste et trier cette dernière : consultez "Comment trier une List (ArrayList, Vector, ...) ou un tableau?" dans la FAQ. L'inconvénient est que l'on ne travaille plus sur le Map et donc on n'a plus un accès direct aux éléments par clés.
  • Ou encore récupérer l'ensemble des clés dans une Liste, la trier suivant les valeurs et accéder aux éléments du Map en parcourant séquentiellement les éléments de cette Liste. L'avantage est qu'on accède toujours aux éléments directement par clé dans le Map. C'est à cette méthode que l'on s'intéressera via un exemple.


Exemple:

Considérons la classe suivante :

 
Sélectionnez

 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é.

 
Sélectionnez

Map<Long, Personne> personnes;


Pour trier ce Map en fonction de l'age des personnes par exemple, on procède comme suit :


1. Créer un Comparator qui compare deux personnes suivant l'age. Le problème est que l'on va trier l'ensemble des clés, donc le Comparator reçoit deux identifiants (Long). Il suffit alors de passer le Map au Comparator dans le constructeur pour que l'on puisse retrouver une personne via son identifiant.

 
Sélectionnez

public class PersonneComparator implements Comparator<Long>{
    private Map<Long, Personne> personnes;//pour garder une copie du Map que l'on souhaite traiter
 
    public PersonneComparator(Map<Long, Personne> personnes){
        this.personnes = personnes; //stocker la copie pour qu'elle soit accessible dans compare()
    }
 
    public int compare(Long id1, Long id2){
        //récupérer les personnes du Map par leur identifiant
        Personne p1 = personnes.get(id1);
        Personne p2 = personnes.get(id2);
 
        //comparer les deux clés en fonction de l'age des personnes qu'ils indexent.
        return p1.getAge() - p2.getAge();
    }
}


2. Trier les clés du Map en utilisant ce Comparator.

 
Sélectionnez

List<Long> cles = new ArrayList<Long>(personnes.keySet());
Collections.sort(cles, new PersonneComparator(personnes));


3. Accéder aux éléments du Map en utilisant la liste triée.

 
Sélectionnez

for(Long id : cles){
      Personne p = personnes.get(id);
      ...
}
Mis à jour le 29 octobre 2008  par djo.mos


On peut parcourir une collection de type Map au moyen d'Iterator. Pour cela, il suffit de récupérer soit les clefs avec la méthode keySet() soit les valeurs avec la méthode values() et d'appeller ensuite la méthode iterator() sur la collection :

Parcours de clefs
Sélectionnez

Map<TypeClefs,TypeValeurs> map = new ClasseImplementantMap<TypeClefs,TypeValeurs> 
 
for (Iterator<TypeClefs> i = map.keySet().iterator() ; i.hasNext() ; ){
    System.out.println(i.next()); 
}
Parcours de valeurs
Sélectionnez

Map<TypeClefs,TypeValeurs> map = new ClasseImplementantMap<TypeClefs,TypeValeurs> 
 
for (Iterator<TypeValeurs> i = map.values().iterator() ; i.hasNext() ;){
    System.out.println(i.next()); 
}


Pour les personnes n'ayant pas Java 5.0, il vous suffira de supprimmer les generics.


On peut aussi récupérer les clefs et les valeurs avec une seule boucler. Il suffit pour cela de boucler sur les clefs et de récupérer ensuite la valeur à partir de la Map :

 
Sélectionnez

Map map = new ClasseImplementantMap();
 
for (Iterator i = map.keySet().iterator() ; i.hasNext() ; ){
    TypeClefs key = i.next();
    System.out.println("key = " + key + " value = " + map.get(key)); 
}


Depuis Java 5.0, on peut aussi utiliser la boucle for étendu pour parcourir une Map. Il suffit d'utiliser la méthode entrySet() qui renvoie une collection de Map.Entry qui représentent un couple clé-valeur. Voici un exemple :

 
Sélectionnez

//Pour récupérer les clefs et les valeurs
for (Map.Entry<TypeClefs, TypeValeurs> e : map.entrySet()){
    System.out.println(e.getKey() + " : " + e.getValue());
}
Créé le 25 août 2007  par le y@m's, Baptiste Wicht, osopardo


Il est déconseillé d'utiliser la classe Vector. En effet, celle-ci fait partie des vieilles du framework de collections de Java. Ces 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 environement multi-threadé 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é 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'utiliser la méthode synchronizedList de la classe Collections :

 
Sélectionnez
List<Object> list = Collections.synchronizedList(new ArrayList<Object>(...));


Vous aurez ainsi une ArrayList tout à fait normale mais synchronisée.

Mis à jour le 20 décembre 2009  par Baptiste Wicht, glob

Lien : ArrayList
Lien : Vector

Les codes sources présentés sur cette page sont libres de droits, et vous pouvez les utiliser à votre convenance. Pour le reste, ce document constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Ce document issu de http://www.developpez.com est soumis à deux licences, en fonction des contributeurs : - Les contributions de Clément Cunin et Johann Heymes sont soumises aux termes de la la licence GNU FDL traduite en français ici. Permission vous est donnée de distribuer, modifier des copies des contributions de Clément Cunin et Johann Heymes tant que cette note apparaît clairement : "Ce document issu de http://www.developpez.com est soumis à la licence GNU FDL traduite en français ici. Permission vous est donnée de distribuer, modifier des copies de cette page tant que cette note apparaît clairement". - Pour ce qui est des autres contributions : Copyright © 2014 Developpez LLC : Tous droits réservés Developpez LLC. Aucune reproduction, ne peut en être faite sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. Cette page est déposée à la SACD.