web-dev-qa-db-fra.com

HashMap vs performances ArrayList suis-je correct

Je crois actuellement que:

  • Lorsque vous avez besoin d'une structure à partir de laquelle vous récupérerez des éléments de manière aléatoire - utilisez un HashMap
  • Quand vous récupérerez les éléments dans l'ordre (par exemple en utilisant une boucle for) - utilisez un ArrayList

Suis-je généralement correct? Y a-t-il des situations où ce n'est pas correct?

35
Ankur

Généralement, oui, vous avez raison. Il existe également une structure de données combinée, le LinkedHashMap , qui offre un accès rapide à des éléments arbitraires ainsi qu'un ordre prévisible.

Cependant, il convient de noter qu'ArrayList et HashMap ne sont que deux implémentations des interfaces List et Map, respectivement. Il existe d'autres implémentations de chacune qui pourraient être plus adaptées à des exigences plus spécifiques. Par exemple, une LinkedList peut fournir des performances supérieures à une ArrayList pour certaines exigences de mise en file d'attente/de mise en file d'attente.

33
harto

Une carte est un carte ou "tableau associatif" . Il a une disposition clé-> valeur. Une liste est par contre un list , qui est une collection ordonnée d'éléments.

Une comparaison plus directe serait probablement entre Set et List: ces deux valeurs contiennent, où la liste est explicitement ordonnée (vous pouvez obtenir l'élément # x), et l'ensemble n'est (généralement) pas ordonné (enfin, sauf s'il s'agit d'un SortedSet , auquel cas l'ordre d'itération sera ordonné par un comparateur).

Les deux implémentations les plus courantes pour Set et List sont HashSet et ArrayList . Pour vérifier si un élément appartient à une liste (contient (element)), l'implémentation parcourt tous les éléments de celui-ci, vérifiant si l'on a trouvé l'élément en utilisant la méthode equals (). Pour vérifier si un élément appartient à un hachage, on calcule d'abord le hashCode () de l'élément, puis on va "directement" à la position où cet élément devrait résider, et vérifie s'il est là.

Ainsi, une différence significative entre ArrayList et HashSet est la vitesse de contains () .

Dans une liste, vous pouvez demander l'élément # x, en plus de ce que vous pouvez faire sur un ensemble, à savoir ajouter, supprimer, demander si présent (contient) et parcourir tous les éléments.

Sur une carte, vous pouvez demander un élément par sa clé, plutôt que par son index comme vous le faites avec une liste.

Un HashSet est actuellement implémenté simplement par un HashMap où la partie valeur de la relation clé-> valeur n'est pas utilisée. C'est complètement absurde et n'a d'autre utilité que de gaspiller au moins 4 octets, pourrait en valoir 12, pour tous les éléments insérés dans le HashSet.

47
stolsvik

Je dirais que vous avez généralement raison, mais que vous n'êtes pas tout à fait exact. Vous utilisez un HashMap pour la récupération des données, mais pas toujours au hasard. Vous utilisez un ArrayList pour l'itération mais vous pouvez également l'utiliser pour des recherches via l'index.

Plus généralement, vous utilisez une implémentation Map lorsque vous avez besoin de récupérer efficacement des éléments par recherche, c'est-à-dire de récupérer quelque chose en fonction de la clé - comme des dictionnaires, des caches, des référentiels, etc.

Vous utilisez une implémentation List lorsque vous souhaitez simplement une structure de données dans laquelle vous pouvez parcourir vos données, généralement lorsque vous les souhaitez dans un ordre prédéterminé et/ou prévisible.

En d'autres termes, vous utilisez Maps comme structure de données d'indexation et vous utilisez Lists comme vous le feriez habituellement avec des tableaux.

10
aberrant80

N'oubliez pas qu'il est également beaucoup plus rapide d'accéder à un élément spécifique avec une carte (si vous avez la clé) qu'à partir d'un tableau (sauf si vous avez un index, mais une clé vous donnera toujours la bonne valeur tout en ayant un l'index peut ne pas fonctionner si de nouveaux éléments sont insérés ou d'anciens supprimés).

Pour moi, c'est plus si je me soucie de la commande des articles de la collection. Si vous vous souciez de la commande, utilisez la liste de tableaux. Si vous ne vous souciez pas de la commande (vous voulez simplement stocker un tas d'articles), vous pouvez utiliser un HashMap.

4
dan gibson

Je serais légèrement en désaccord. Pour moi, cela dépend plus de la façon dont je veux récupérer les articles. Si je veux le faire sur la base de quelque chose comme leur ordre (par index, pour être précis), j'aurais tendance à utiliser une structure linéaire comme une ArrayList (ou même un tableau). Si je dois rechercher des éléments, j'utiliserais une structure de carte comme HashMap.

Un autre facteur de complication est lié aux insertions et à l'ordre, comme l'a souligné dan.

2
CPerkins