web-dev-qa-db-fra.com

Que se passe-t-il lorsqu'une clé en double est insérée dans un HashMap?

Si je passe la même clé plusieurs fois à la méthode HashMap’s s put, qu’advient-il de la valeur initiale? Et si même la valeur se répète? Je n’ai trouvé aucune documentation à ce sujet.

Cas 1: valeurs écrasées pour une clé

Map mymap = new HashMap();
mymap.put("1","one");
mymap.put("1","not one");
mymap.put("1","surely not one");
System.out.println(mymap.get("1"));

Nous obtenons surely not one.

Cas 2: valeur en double

Map mymap = new HashMap();
mymap.put("1","one");
mymap.put("1","not one");
mymap.put("1","surely not one");
// The following line was added:
mymap.put("1","one");
System.out.println(mymap.get("1"));

Nous obtenons one.

Mais qu'advient-il des autres valeurs? J'enseignais les bases à un étudiant et on m'a posé cette question. Est-ce que Map est comme un compartiment où la dernière valeur est référencée (mais en mémoire)?

244
boodieye

Par définition, la commande put remplace la valeur précédente associée à la clé donnée dans la carte (conceptuellement, comme une opération d'indexation de tableau pour les types primitifs).

La carte laisse simplement sa référence à la valeur. Si rien d'autre ne contient de référence à l'objet, cet objet devient éligible pour le garbage collection. De plus, Java renvoie toutes les valeurs précédentes associées à la clé donnée (ou à null si aucune n'est présente). Vous pouvez donc déterminer ce qui était présent et conserver une référence si nécessaire.

Plus d'informations ici: HashMap Doc

281
jheddings

Vous pouvez trouver votre réponse dans le javadoc de Map # put (K, V) (qui renvoie en réalité quelque chose):

public V put(K key,
             V value)

Associe la valeur spécifiée à la clé spécifiée dans cette carte (opération facultative). Si la carte contenait auparavant un mappage pour cette clé, l'ancienne valeur est remplacée par la valeur spécifiée. (Une mappe m est censée contenir un mappage pour une clé k si Et seulement si m.containsKey(k) serait Retournera true.

Paramètres:
key - clé à laquelle la valeur spécifiée doit être associée.
value - valeur à associer à la clé spécifiée. 

Résultats:
valeur précédente associée à la clé spécifiée, ou null s'il n'y avait pas de mappage pour key. (Un retour null peut également indiquer que la carte précédemment associée null à la key spécifiée, si l'implémentation prend en charge les valeurs null.)

Ainsi, si vous n'attribuez pas la valeur renvoyée lorsque vous appelez mymap.put("1", "a string"), elle ne sera plus référencée et sera donc éligible pour le garbage collection.

70
Pascal Thivent

La valeur précédente de la clé est supprimée et remplacée par la nouvelle.

Si vous souhaitez conserver toutes les valeurs associées à une clé, vous pouvez envisager d'implémenter quelque chose comme ceci:

import org.Apache.commons.collections.MultiHashMap;
import Java.util.Set;
import Java.util.Map;
import Java.util.Iterator;
import Java.util.List;
public class MultiMapExample {

   public static void main(String[] args) {
      MultiHashMap mp=new MultiHashMap();
      mp.put("a", 10);
      mp.put("a", 11);
      mp.put("a", 12);
      mp.put("b", 13);
      mp.put("c", 14);
      mp.put("e", 15);
      List list = null;

      Set set = mp.entrySet();
      Iterator i = set.iterator();
      while(i.hasNext()) {
         Map.Entry me = (Map.Entry)i.next();
         list=(List)mp.get(me.getKey());

         for(int j=0;j<list.size();j++)
         {
          System.out.println(me.getKey()+": value :"+list.get(j));
         }
      }
   }
}
18
kamlesh0606

c'est la fonction clé/valeur et vous ne pouvez pas avoir la clé en double pour plusieurs valeurs car lorsque vous voulez obtenir la valeur réelle, laquelle des valeurs appartient à la clé entrée
dans votre exemple, lorsque vous voulez obtenir la valeur "1", lequel est-ce?!
c’est une raison pour avoir une clé unique pour chaque valeur, mais vous pouvez avoir une astuce avec la bibliothèque standard Java:

import Java.util.ArrayList;
import Java.util.HashMap;
import Java.util.Map;

public class DuplicateMap<K, V> {

    private Map<K, ArrayList<V>> m = new HashMap<>();

    public void put(K k, V v) {
        if (m.containsKey(k)) {
            m.get(k).add(v);
        } else {
            ArrayList<V> arr = new ArrayList<>();
            arr.add(v);
            m.put(k, arr);
        }
    }

     public ArrayList<V> get(K k) {
        return m.get(k);
    }

    public V get(K k, int index) {
        return m.get(k).size()-1 < index ? null : m.get(k).get(index);
    }
}


et vous pourriez l'utiliser de cette façon:

    public static void main(String[] args) {
    DuplicateMap<String,String> dm=new DuplicateMap<>();
    dm.put("1", "one");
    dm.put("1", "not one");
    dm.put("1", "surely not one");
    System.out.println(dm.get("1"));
    System.out.println(dm.get("1",1));
    System.out.println(dm.get("1", 5));
}

et le résultat des impressions sont:

[one, not one, surely not one]
not one
null
17
java acm

Associe la valeur spécifiée à la clé spécifiée dans cette carte. Si la carte contenait précédemment un mappage pour la clé, l'ancienne valeur est remplacée.

11
Diego Alejandro

A votre question de savoir si la carte ressemblait à un seau: non.

C'est comme une liste avec des paires name=value alors que name n'a pas besoin d'être une chaîne (c'est possible, cependant).

Pour obtenir un élément, vous passez votre clé à la méthode get () - qui vous donne l'objet assigné en retour.

Et une carte Hash signifie que si vous essayez de récupérer votre objet à l'aide de la méthode get, il ne comparera pas l'objet réel à celui que vous avez fourni, car il devra parcourir la liste et comparer () la clé fournie avec l'élément en cours.

Ce serait inefficace. Peu importe la nature de votre objet, il calcule un code de hachage à partir des deux objets et le compare. Il est plus facile de comparer deux ints au lieu de deux objets entiers (peut-être profondément complexes). Vous pouvez imaginer le hashcode comme un résumé ayant une longueur prédéfinie (int), il n'est donc pas unique et présente des collisions. Vous trouvez les règles pour le hashcode dans la documentation à laquelle j'ai inséré le lien.

Si vous souhaitez en savoir plus à ce sujet, vous pouvez consulter des articles sur javapractices.com et technofundo.com

cordialement

4
Atmocreations

J'ai toujours utilisé:

HashMap<String, ArrayList<String>> hashy = new HashMap<String, ArrayList<String>>();

si je voulais appliquer plusieurs choses à une clé d'identification. 

public void MultiHash(){
    HashMap<String, ArrayList<String>> hashy = new HashMap<String, ArrayList<String>>();
    String key = "Your key";

    ArrayList<String> yourarraylist = hashy.get(key);

    for(String valuessaved2key : yourarraylist){
        System.out.println(valuessaved2key);
    }

}

vous pouvez toujours faire quelque chose comme ça et créer vous-même un labyrinthe!

public void LOOK_AT_ALL_THESE_HASHMAPS(){
    HashMap<String, HashMap<String, HashMap<String, HashMap<String, String>>>> theultimatehashmap = new HashMap <String, HashMap<String, HashMap<String, HashMap<String, String>>>>();
    String ballsdeep_into_the_hashmap = theultimatehashmap.get("firststring").get("secondstring").get("thirdstring").get("forthstring");
}
3
sheepiiHD

Oui, cela signifie que toutes les clés 1 ayant une valeur sont écrasées avec la dernière valeur ajoutée et que vous ajoutez ici "sûrement pas une", ainsi il affichera uniquement "sûrement pas une".

Même si vous essayez d’afficher avec une boucle, il n’affichera qu’une clé et une valeur ayant la même clé.

1
ajaynakrani

BTW, si vous voulez des sémantiques telles que put si cette clé n’existe pas. vous pouvez utiliser concurrentHashMap avec putIfAbsent() fonction .

https://docs.Oracle.com/javase/7/docs/api/Java/util/concurrent/ConcurrentHashMap.html#put(K,%20V) }

concurrentHashMap est thread-safe et offre de hautes performances puisqu'il utilise le mécanisme "STRIP STRIP)" pour améliorer le débit. 

1
BufBills

Ilremplace la valeur existantedans la carte pour la clé respective. Et si aucune clé n'existe avec le même nom, elle crée une clé avec la valeur fournie . Exemple:

Map mymap = new HashMap();
mymap.put("1","one");
mymap.put("1","two");

SORTIE clé = "1", valeur = "deux"

Ainsi, la valeur précédente est écrasée.

0
Bishal Jaiswal