L'ajout d'une valeur en double à un HashSet / HashMap remplace-t-il la valeur précédente

Veuillez considérer le code ci-dessous:

HashSet hs = new HashSet();
hs.add("hi"); -- (1)
hs.add("hi"); -- (2)

hs.size() donnera 1 car HashSet n'autorise pas les doublons, donc un seul élément sera stocké.

Je veux savoir si nous ajoutons l'élément dupliqué, alors remplace-t-il l'élément précédent ou il ne l'ajoute tout simplement pas?

Aussi, que se passera-t-il en utilisantHashMap pour le même cas?

103
demandé sur Raedwald 2012-10-17 22:14:14

8 réponses

Dans le cas de HashMap, elle remplace l'ancienne valeur par la nouvelle.

Dans le cas de HashSet, l'élément n'est pas inséré.

184
répondu Keppil 2012-10-17 18:14:55

La première chose que vous devez savoir est que HashSet agit comme un Set, ce qui signifie que vous ajoutez votre objet directement au HashSet et qu'il ne peut pas contenir de doublons. Vous ajoutez simplement votre valeur directement dans HashSet.

Cependant, HashMap est un type Map. Cela signifie que chaque fois que vous ajoutez une entrée, vous ajouter une paire clé-valeur.

Dans HashMap, vous pouvez avoir des valeurs en double, mais pas des doubles des clés. Dans HashMap la nouvelle entrée remplacera l'ancien. L'entrée la plus récente sera dans le HashMap.

Comprendre le lien entre HashMap et HashSet:

Rappelez-vous, HashMap ne peut pas avoir des clés en double. Derrière la scène HashSet utilise HashMap.

Lorsque vous tentez d'ajouter un objet dans un HashSet, cette entrée est stockée comme une clé dans le HashMap - même HashMap, ce qui est utilisé derrière la scène de HashSet. Puisque ce sous-jacent HashMap a besoin d'une paire clé-valeur, une valeur fictive est générée pour nous.

Maintenant, lorsque vous essayez d'insérer un autre objet en double dans le même HashSet, il tentera à nouveau de l'insérer comme clé dans le HashMap situé en dessous. Cependant, HashMap ne prend pas en charge les doublons. Par conséquent, HashSet aura toujours une seule valeur de ce type. Comme une note de côté, pour chaque clé en double, puisque la valeur générée pour notre entrée dans HashSet est une valeur aléatoire/fictive, la clé n'est pas remplacée du tout. il sera ignoré car la suppression de la clé et l'ajout de la même clé (la valeur fictive est la même) n'aurait aucun sens à tout.

Résumé:

HashMap permet de dupliquer values, mais pas keys. HashSet ne peut pas contenir de doublons.

Pour savoir si l'ajout d'un objet est réussi ou non, vous pouvez vérifier la valeur boolean renvoyée lorsque vous appelez .add() et voir si elle renvoie true ou false. S'il renvoyait true, Il était inséré.

38
répondu Jimmy 2016-04-14 23:00:10

Les docs sont assez clairs à ce sujet: HashSet.add ne remplace pas :

Ajoute l'élément spécifié à cet ensemble s'il n'est pas déjà présent. Plus formellement, ajoute l'élément spécifié e pour cet ensemble si cet ensemble ne contient aucun élément e2 telle que (f==null ? e2 = = null: E. est égal à (e2)). Si cet ensemble contient déjà l'élément, l'appel laisse l'ensemble inchangé et renvoie false.

Mais HashMap.put sera remplacer:

Si la carte contenait précédemment un mappage pour la clé, l'ancienne valeur est remplacée.

14
répondu pb2q 2012-10-17 20:50:12

C'est le cas de HashSet, il ne le remplace pas.

À partir des documents:

Http://docs.oracle.com/javase/6/docs/api/java/util/HashSet.html#add(E)

" ajoute l'élément spécifié à cet ensemble s'il n'est pas déjà présent. Plus formellement, ajoute l'élément spécifié e pour cet ensemble si cet ensemble ne contient aucun élément e2 telle que (f==null ? e2 = = null: E. est égal à (e2)). Si cet ensemble contient déjà l'élément, l'appel laisse l'ensemble inchangé et renvoie false."

3
répondu Bob Provencher 2012-10-17 18:29:17

Corrigez-moi si je me trompe mais ce que vous voulez dire, c'est qu'avec des chaînes, "Hi" == "Hi" ne sort pas toujours vrai (parce qu'ils ne sont pas nécessairement le même objet).

La raison pour laquelle vous obtenez une réponse de 1 est que la JVM réutilisera les objets strings si possible. Dans ce cas, la JVM réutilise l'objet string et écrase ainsi l'élément dans le Hashmap/Hashset.

Mais ce comportement n'est pas garanti (car il pourrait s'agir d'une chaîne différente objet qui a la même valeur "Salut"). Le comportement que vous voyez est juste à cause de l'optimisation de la JVM.

1
répondu Nick Rippe 2012-10-17 18:19:25

Vous devez d'abord vérifier la méthode put dans la carte de hachage car HashSet est sauvegardé par HashMap

  1. Lorsque vous ajoutez une valeur en double, dites une chaîne " One " dans HashSet,
  2. Une entrée ("one", PRESENT) sera insérée dans Hashmap (pour tous les valeurs ajoutées dans set, la valeur sera "présente" qui si de type Object)
  3. HashMap ajoute l'entrée dans Map et renvoie la valeur, qui est dans ce cas "PRESENT" ou null si L'entrée n'est pas là.
  4. la méthode add de Hashset retourne alors true si la valeur renvoyée par Hashmap est égale à null sinon false ce qui signifie qu'une entrée existe déjà...
0
répondu shiv 2014-09-09 15:57:42

Pour le dire différemment: lorsque vous insérez une paire clé-valeur dans un HashMap où la clé existe déjà (dans un sens hashvalue () donne la même valeur und equal () est vrai, mais les deux objets peuvent toujours différer de plusieurs façons), la clé n'est pas remplacée mais la valeur est écrasée. La clé est juste utilisée pour obtenir le hashvalue() et trouver la valeur dans la table avec elle. Puisque HashSet utilise les clés D'un HashMap et définit des valeurs arbitraires qui n'ont pas vraiment d'importance (pour l'utilisateur), les éléments de L'ensemble ne sont pas remplacés non plus.

0
répondu Marco Rothley 2016-08-24 09:04:24

HashMap contient essentiellement une entrée qui contient ensuite des clés (objet) et une valeur(objet).En interne HashSet sont HashMap et HashMap ne remplace les valeurs que certains d'entre vous ont déjà souligné..mais remplace-t-il vraiment les clés???Aucun ..et c'est l'astuce ici.HashMap conserve sa valeur comme clé dans le HashMap sous jacent et la valeur est juste un mannequin object.So si vous essayez de réinsérer la même valeur dans HashMap (clé dans la carte sous-jacente). il remplace simplement la valeur fictive et non la clé (valeur pour HashSet).

Regardez le code ci-dessous pour la classe HashSet:

Public booléen [plus ...] add (E e) {

   return map.put(e, PRESENT)==null;
}

Ici e est la valeur pour HashSet mais la clé pour la carte sous-jacente.et la clé n'est jamais remplacé. J'espère que je suis capable d'effacer la confusion.

0
répondu Kunal Kumar 2017-12-04 05:13:30