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)?
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
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 sim.containsKey(k)
serait Retourneratrue
.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, ounull
s'il n'y avait pas de mappage pourkey
. (Un retournull
peut également indiquer que la carte précédemment associéenull
à lakey
spécifiée, si l'implémentation prend en charge les valeursnull
.)
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.
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));
}
}
}
}
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
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.
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 int
s 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
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");
}
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é.
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.
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.