Parcourir un objet Map
Plusieurs solutions existent pour parcourir une interface Map
. Mais sont-elles toujours optimales ?
En Java, l’interface Map
permet de définir une liste d’association entre clés et valeurs. Ainsi à partir d’une clé, il est possible de retrouver la valeur correspondante.
Une bonne démarche pour parcourir un objet implémentant l’interface Map
, est d’utiliser les itérateurs définis par l’interface Iterator
. L’interface Map
propose trois méthodes qui retournent une Collection
à partir de laquelle il est possible d’accéder à un itérateur :
public Set entrySet();
retourne la liste des couples clé/valeurpublic Set keySet();
donne la liste des cléspublic Collection values();
permet d’obtenir la liste des valeurs
Lorsque l’on parcourt une Map
, il est souvent nécessaire de connaître à la fois la clé et la valeur. Beaucoup de personnes sont alors tenté d’écrire[1] :
Map map; for ( Iterator i = map.keySet().iterator(); i.hasNext();) { Cle cle = (Cle)i.next(); Valeur valeur = (Valeur)map.get(cle); /* Utilisation des objets cle et valeur */ }
Ce bout de code fonctionne très bien. Pourtant il n’est pas optimal. En effet, on commence par récupérer la liste des clés. Puis pour chaque clé, on recherche la valeur correspondante. Or, il est préférable de récupérer en une seule passe les clés et les valeurs. Pour cela il faut faire appel à la méthode entrySet()
:
Map map; for ( Iterator i = map.entrySet().iterator(); i.hasNext();) { Entry couple = (Entry)i.next(); Cle cle = (Cle)coupe.getKey(); Valeur valeur = (Valeur)couple.getValue(); /* Utilisation des objets cle et valeur */ }
Cet exemple, montre qu’il faut prendre le temps de lire la JavaDoc. Ceci afin d’utiliser de façon optimale l’API très riche offerte par le JDK. Ce type d’optimisation permet parfois de gagner énormément en performance. Car c’est le genre de boucle qui revient souvent dans le code source.
Notes
[1] Enfin, cet algorithme n’est pas rare…
Est-ce que tu as fait un test de perf pour comparer les 2 méthodes par hasard.
C’est vrai que je n’ai pas effectué de test de performance. Ta remarque est pertinante, je vais réaliser quels tests…
Aurais-tu les informations sur ce sujet ? As-tu déja fait quelques tests ?
Non mais je me posais la question concernant les perfs justement 🙂
Après avoir faire quelques tests, je confirme que la seconde méthode est plus rapide. Les tests ont été réalisé avec des objets simple pour les clés. La recherche dans les Map devait être assez rapide. Avec des objets plus complexes, les résultats seraient encore plus significatifs.
Pour information, j’ai obtenu un facteur 1,5-2 sur l’ensemble des tests. Ce résultat n’est pas à prendre pour argent comptant puisqu’il dépend de l’implémentation de Map utilisée, du nombre d’éléments dans la Map et la complexité des objets utilisés en tant que clés.
A défaut de donner un facteur d’optimisation, ce test permet de confirmer l’amélioration des performances.