301 votes

Que se passe-t-il lorsqu'une clé dupliquée est placée dans un HashMap ?

Si je passe la même clé plusieurs fois à HashMap 's put qu'advient-il de la valeur originale ? Et que se passe-t-il si même la valeur se répète ? Je n'ai pas trouvé de 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"));

On obtient surely not one .

Cas 2 : Valeur dupliquée

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"));

On obtient one .

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

7 votes

D'ailleurs, c'est une excellente occasion de montrer le multi-hashmap qui fait partie des classes de collections Jakarta ( commons.apache.org/collections ). Il vous permettra d'avoir un nombre quelconque de valeurs associées à la même clé, pour les fois où vous en aurez besoin.

0 votes

328voto

jheddings Points 10510

Par définition, le 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 supprime simplement sa référence à la valeur. Si rien d'autre ne détient une référence à l'objet, celui-ci devient éligible à la collecte des déchets. En outre, Java renvoie toute valeur antérieure associée à la clé (ou à l'objet de la carte) donnée. null s'il n'y en a pas), afin que vous puissiez déterminer ce qui était là et maintenir une référence si nécessaire.

Plus d'informations ici : Doc HashMap

0 votes

Merci pour cela. En lisant la documentation Java, cela n'est pas clairement mentionné. Je suppose que l'auteur de la documentation a supposé que c'était une hypothèse tacite de toutes les implémentations de cartes de hachage.

0 votes

J'ai lu l'implémentation Java et il semble que lorsque vous insérez une nouvelle paire clé-valeur, il faut itérer sur tous les éléments du seau pour savoir si la clé existe ou non, donc il ne peut pas simplement ajouter un élément à la fin du seau. L'insertion n'est donc pas 100% O(1).

83voto

Pascal Thivent Points 295221

Vous pouvez trouver votre réponse dans la javadoc de Map#put(K, V) (qui renvoie effectivement 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 précédemment un mappage pour cette clé, l'ancienne valeur est remplacée par la valeur spécifiée. (Une carte m est dit contient un mappage pour une clé k si et seulement si m.containsKey(k) serait renvoyer true .)

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

Les retours :
valeur précédente associée à la clé spécifiée, ou null s'il n'y avait pas de cartographie pour key . (A null Le retour peut également indiquer que la carte précédemment associée null avec l'option spécifiée key si l'implémentation supporte null valeurs.)

Donc, si vous n'assignez pas la valeur retournée lorsque vous appelez mymap.put("1", "a string") il devient simplement non référencé et donc éligible à la collecte des déchets.

3 votes

Le site valeur retournée est le valeur précédente (ou null ) comme documenté juste au-dessus dans la javadoc donc, oui, c'est ce que je veux dire. Cela peut-il vraiment être mal interprété ?

0 votes

C'est très utile.

22voto

java acm Points 654

Il s'agit d'une fonction de clé/valeur et vous ne pouvez pas avoir de clé dupliquée pour plusieurs valeurs car lorsque vous voulez obtenir la valeur réelle, laquelle des valeurs appartient à la clé saisie.
dans votre exemple, lorsque vous voulez obtenir la valeur de "1", quelle est la valeur ? !
c'est la raison pour laquelle il faut avoir une clé unique pour chaque valeur, mais vous pouvez utiliser la librairie standard de 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 les résultats des impressions sont :

[one, not one, surely not one]
not one
null

21voto

Bishal Jaiswal Points 512

Il remplace la valeur existante dans la carte pour la clé correspondante. Et si aucune clé n'existe avec le même nom, il crée une clé avec la valeur fournie. Par 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.

18voto

kamlesh0606 Points 226

La valeur antérieure de la clé est abandonnée et remplacée par la nouvelle.

Si vous souhaitez conserver toutes les valeurs attribuées à une clé, vous pouvez envisager de mettre en œuvre 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));
         }
      }
   }
}

1 votes

Cette solution est déprécarisée. MultiHashMap fait partie de apache.commons.collections et non de java.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X