J'avais à l'origine écrit un ArrayList
et stocké des valeurs uniques (noms d'utilisateur, c'est-à-dire Strings
) dedans. Plus tard, j'ai dû utiliser le ArrayList
pour rechercher si un utilisateur y existait. C'est O(n)
pour la recherche.
Mon responsable technique voulait que je change cela en HashMap
et que je stocke les noms d'utilisateur sous forme de clés dans le tableau et les valeurs sous vide Strings
.
Donc, en Java -
hashmap.put("johndoe","");
Je peux voir si cet utilisateur existe plus tard en exécutant -
hashmap.containsKey("johndoe");
C'est O(1)
non?
Mon responsable a dit que c'était un moyen plus efficace de le faire et que cela avait du sens pour moi, mais il semblait juste un peu décalé de mettre null/empty en tant que valeurs dans la table de hachage et de stocker des éléments en tant que clés.
Ma question est la suivante: est-ce une bonne approche? L'efficacité bat ArrayList#contains
Ou une recherche de tableau en général. Ça marche. Mon inquiétude est que je n'ai vu personne faire cela après une recherche. Je manque peut-être un problème évident quelque part, mais je ne le vois pas.
Puisque vous avez un ensemble de valeurs uniques, un Set
est la structure de données appropriée. Vous pouvez placer vos valeurs dans HashSet
, une implémentation de l'interface Set
.
Mon responsable a dit que c'était un moyen plus efficace de le faire et que cela avait du sens pour moi, mais cela semblait juste un peu décalé de mettre null/empty en tant que valeurs dans la table de hachage et de stocker des éléments en tant que clés.
L'avis du responsable est imparfait. Map
n'est pas la bonne abstraction pour cela, Set
l'est. Un Map
est approprié pour les paires clé-valeur. Mais vous n'avez pas de valeurs, seulement des clés.
Exemple d'utilisation:
Set<String> users = new HashSet<>(Arrays.asList("Alice", "Bob"));
System.out.println(users.contains("Alice"));
// -> prints true
System.out.println(users.contains("Jack"));
// -> prints false
Utiliser un Map
serait gênant, car quel devrait être le type des valeurs? Cette question n'a aucun sens dans votre cas d'utilisation, car vous n'avez que des clés, pas des paires clé-valeur. Avec un Set
, vous n'avez pas besoin de demander cela, l'utilisation est parfaitement naturelle.
C'est O(1) non?
Oui, la recherche dans un HashMap
ou un HashSet
est O(1) amorti dans le pire des cas, tandis que la recherche dans un List
ou un tableau est O(n) pire cas.
Certains commentaires soulignent qu'un HashSet
est implémenté en termes de HashMap
. C'est très bien, à ce niveau d'abstraction. Au niveau de l'abstraction de la tâche à accomplir --- pour stocker une collection de noms d'utilisateur uniques, utiliser un ensemble est un choix naturel, plus naturel qu'une carte.
C'est essentiellement la façon dont HashSet
est implémenté, donc je suppose que vous pouvez dire que c'est une bonne approche. Vous pourriez aussi bien utiliser HashSet
au lieu de votre HashMap
avec des valeurs vides.
Par exemple :
L'implémentation de HashSet
par add
est
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
où map
est le support HashMap
et PRESENT
est une valeur fictive.
Mon inquiétude est que je n'ai vu personne faire cela après une recherche. Je manque peut-être un problème évident quelque part, mais je ne le vois pas.
Comme je l'ai mentionné, les développeurs du JDK utilisent cette même approche.