Est-il possible de renommer une clé Hashmap?

89

Je cherche un moyen de renommer une clé Hashmap, mais je ne sais pas si c'est possible en Java.

Ikes
la source
11
Gosh, j'espère que non. Supprimer et saisir à nouveau la paire clé / valeur semble être la voie à suivre. Notez que vous ne gérez normalement que les références dans la carte elle-même de toute façon.
Maarten Bodewes
4
Veuillez ne pas modifier la clé d'une entrée de hachage! Si vous avez de la chance, vous le changerez en quelque chose avec le même hashcode et vous deviendrez un peu fou en essayant de comprendre ce qui s'est passé; si vous n'avez pas de chance, vous vous retrouverez avec une entrée qui ne peut pas être trouvée (enfin, pas avant la prochaine reconstruction de la table entière). Supprimer / réinsérer est beaucoup plus sain et devrait être assez bon marché (ce sont toutes des références, après tout).
Donal Fellows

Réponses:

137

Essayez de supprimer l'élément et de le remettre avec le nouveau nom. En supposant que les clés de votre carte le sont String, cela pourrait être réalisé de cette façon:

Object obj = map.remove("oldKey");
map.put("newKey", obj);
Alexis Pigeon
la source
59
+1. Et le plus simple à lire est map.put( "newKey", map.remove( "oldKey" ) );et contientoldKey
Ravinder Reddy
15
En ce qui concerne la lisibilité, je ne suis pas du tout d'accord, je préfère personnellement voir clairement qu'un objet est retiré de la carte, puis ajouté. Et comme l'OP semble être assez nouveau pour Java, j'ai décidé de le dire de cette façon. Pour des raisons de performances cependant, votre version est bien sûr préférée (puisque je ne pense pas que le compilateur optimisera ma version à votre façon).
Alexis Pigeon
3
Pour javac 1.8.0_45, la version en une ligne est plus courte de deux bytecodes, ce qui m'a surpris. Plus ennuyeux avec les génériques, vous ne pouvez pas passer objà putsans le lancer ou le déclarer comme un autre type, mais bien sûr, passer le résultat de removefonctionne directement.
Samuel Edwin Ward du
1
Mais comment renommer toutes les clés
gstackoverflow
4
Cela mènera à ConcurrentModificationException
gstackoverflow
19

Attribuez la valeur de la clé, qui doit être renommée, à une nouvelle clé. Et retirez l'ancienne clé.

hashMap.put("New_Key", hashMap.get("Old_Key"));
hashMap.remove("Old_Key");
Deepak Mani
la source
19
hashMap.put("New_Key", hashMap.remove("Old_Key"));

Cela fera ce que vous voulez, mais vous remarquerez que l'emplacement de la clé a changé.

Mohamed Zakaria El-Zoghbi
la source
@Vins revisite les documentations s'il vous plaît: D, remove () retournera l'objet, vérifiez ce tutorialspoint.com/java/util/hashmap_remove.htm
Mohamed Zakaria El-Zoghbi
1
mon mauvais, j'ai supprimé mon commentaire et voté pour. Désolé pour ça.
Vins
9

Vous ne pouvez pas renommer / modifier la clé hashmap fois ajoutée.

Le seul moyen est de supprimer / supprimer la clé et de l'insérer avec une nouvelle paire clé et valeur.

Raison : dans l'implémentation interne de hashmap, le modificateur de touche Hashmap marqué comme final.

static class Entry<K ,V> implements Map.Entry<K ,V>
{
 final K key;
 V value;
 Entry<K ,V> next;
 final int hash;
...//More code goes here
}

Pour référence: HashMap

rayon de lumière
la source
4

Vous ne renommez pas une clé hashmap, vous devez insérer une nouvelle entrée avec la nouvelle clé et supprimer l'ancienne.

Hari Menon
la source
2

Je dirais que l'essence des clés hasmap sont à des fins d'accès à l'index et rien de plus, mais voici un hack: créer une classe de wrapper de clé autour de la valeur de la clé afin que l'objet key-wrapper devienne la clé de hashmap pour l'accès à l'index, donc vous peut accéder et modifier la valeur de l'objet key-wrapper pour vos besoins spécifiques:

public class KeyWrapper<T>{

      private T key;
      public KeyWrapper(T key){
         this.key=key;
       }

      public void rename(T newkey){
              this.key=newkey;
       }

}

Exemple

   HashMap<KeyWrapper,String> hashmap=new HashMap<>();
   KeyWrapper key=new KeyWrapper("cool-key");
   hashmap.put(key,"value");
   key.rename("cool-key-renamed");

Bien que vous puissiez également avoir une clé non existante être en mesure d'obtenir la valeur d'une clé existante à partir de la hashmap, mais je crains que cela puisse être criminel, de toute façon:

public  class KeyWrapper<T>{

        private T key;
        public KeyWrapper(T key){
            this.key=key;
        }

        @Override
        public boolean equals(Object o) {
            return hashCode()==o.hashCode();
        }

        @Override
        public int hashCode() {
            int hash=((String)key).length();//however you want your hash to be computed such that two different objects may share the same at some point
            return hash;
        }
    }

Exemple

HashMap<KeyWrapper,String> hashmap=new HashMap<>();
KeyWrapper cool_key=new KeyWrapper("cool-key");
KeyWrapper fake_key=new KeyWrapper("fake-key");
hashmap.put(cool_key,"cool-value");
System.out.println("I don't believe it but its: "+hashmap.containsKey(fake_key)+" OMG!!!");
LiNKeR
la source
1

Veuillez regarder ci-dessous les points:

1) No,You can not rename the key of hashmap once added.

 2) Very first you have to delete or remove that key and then you can insert with new key with value.

 3) Because in hashmap internal implementation the Hashmap key modifier  is final.
Ghanshyam
la source
0

Vous pouvez, si au lieu de Java HashMap natif, vous utiliserez un Bimap .
Ce n'est pas l'implémentation traditionnelle de Map, et vous devez vous assurer qu'elle répond à vos besoins.

Un bimap (ou "bidirectional map") est une carte qui préserve l'unicité de ses valeurs ainsi que celle de ses clés. Cette contrainte permet aux bimaps de prendre en charge une «vue inverse», qui est une autre bimap contenant les mêmes entrées que cette bimap mais avec des clés et des valeurs inversées.

À l'aide d'un bimap, vous pouvez inverser la vue et remplacer la clé. Découvrez
Apache Commons BidiMap et Guava BiMap .

Dorony
la source
0

Dans mon cas, il y avait une carte contenant des clés non réelles -> des clés réelles, j'ai donc dû remplacer les non réels par les réels de ma carte (l'idée est comme les autres)

getFriendlyFieldsMapping().forEach((friendlyKey, realKey) ->
    if (map.containsKey(friendlyKey))
        map.put(realKey, map.remove(friendlyKey))
);
Basheer AL-MOMANI
la source