Ist es möglich, einen Hashmap-Schlüssel umzubenennen?


89

Ich suche nach einer Möglichkeit, einen Hashmap-Schlüssel umzubenennen, aber ich weiß nicht, ob dies in Java möglich ist.


11
Meine Güte, ich hoffe nicht. Das Löschen und erneute Eingeben des Schlüssel / Wert-Paares scheint der richtige Weg zu sein. Beachten Sie, dass Sie normalerweise ohnehin nur Referenzen in der Karte selbst verarbeiten.
Maarten Bodewes

4
Bitte ändern Sie nicht den Schlüssel eines Hash-Eintrags! Wenn Sie Glück haben, ändern Sie es in etwas mit demselben Hashcode und werden einfach etwas verrückt, wenn Sie herausfinden wollen, was passiert ist. Wenn Sie Pech haben, erhalten Sie einen Eintrag, der nicht gefunden werden kann (erst beim nächsten Wiederaufbau der gesamten Tabelle). Entfernen / Wiedereinsetzen ist viel vernünftiger und sollte ziemlich billig sein (es sind schließlich alle Referenzen).
Donal Fellows

Antworten:


136

Versuchen Sie, das Element zu entfernen und erneut mit dem neuen Namen zu versehen. Angenommen, die Schlüssel in Ihrer Karte sind String, könnte dies folgendermaßen erreicht werden:

Object obj = map.remove("oldKey");
map.put("newKey", obj);

58
+1. Und am einfachsten zu lesen ist map.put( "newKey", map.remove( "oldKey" ) );und zur Verfügung gestellt enthältoldKey
Ravinder Reddy

14
In Bezug auf die Lesbarkeit bin ich völlig anderer Meinung. Ich persönlich möchte lieber klar sehen, dass ein Objekt von der Karte entfernt und dann hinzugefügt wird. Und da das OP für Java ziemlich neu zu sein scheint, habe ich mich dazu entschlossen, es so auszudrücken. Aus Gründen der Leistung wird Ihre Version natürlich bevorzugt (da ich nicht glaube, dass der Compiler meine Version auf Ihre Weise optimieren wird).
Alexis Pigeon

3
Für javac 1.8.0_45 ist die einzeilige Version zwei Bytecodes kürzer, was mich überrascht hat. Ärgerlicher bei Generika, auf die man nicht übergehen kann obj, putohne sie zu gießen oder als einen anderen Typ zu deklarieren, aber natürlich das Ergebnis von removedirekt funktioniert.
Samuel Edwin Ward

1
Aber wie man alle Schlüssel umbenennt
gstackoverflow

4
Es wird zu ConcurrentModificationException
gstackoverflow

18

Weisen Sie einem neuen Schlüssel den Wert des Schlüssels zu, der umbenannt werden muss. Und entfernen Sie den alten Schlüssel.

hashMap.put("New_Key", hashMap.get("Old_Key"));
hashMap.remove("Old_Key");

17
hashMap.put("New_Key", hashMap.remove("Old_Key"));

Dies wird tun, was Sie wollen, aber Sie werden feststellen, dass sich die Position des Schlüssels geändert hat.


@Vins überprüfen Sie die Dokumentationen bitte: D, remove () wird das Objekt zurückgeben, überprüfen Sie dieses Tutorialspoint.com/java/util/hashmap_remove.htm
Mohamed Zakaria El-Zoghbi

1
Mein schlechtes, ich habe meinen Kommentar entfernt und dafür gestimmt. Das tut mir leid.
Vins

8

Sie können den Hashmap- Schlüssel nicht umbenennen / ändern einmal hinzugefügten .

Die einzige Möglichkeit besteht darin, den Schlüssel zu löschen / entfernen und mit einem neuen Schlüssel-Wert-Paar einzufügen.

Grund : In der internen Implementierung von Hashmap wird der Hashmap-Schlüsselmodifikator als endgültig markiert.

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
}

Als Referenz: HashMap


4

Sie benennen einen Hashmap-Schlüssel nicht um, sondern müssen einen neuen Eintrag mit dem neuen Schlüssel einfügen und den alten löschen.


2

Ich würde behaupten, dass die Essenz von Hashmap-Schlüsseln für Indexzugriffszwecke dient und nichts weiter als ein Hack: Erstellen einer Key-Wrapper-Klasse um den Wert des Schlüssels, sodass das Key-Wrapper-Objekt zum Hashmap-Schlüssel für den Indexzugriff wird kann auf den Wert des Key-Wrapper-Objekts zugreifen und diesen für Ihre spezifischen Anforderungen ändern:

public class KeyWrapper<T>{

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

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

}

Beispiel

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

Sie könnten zwar auch einen nicht vorhandenen Schlüssel haben, um den Wert eines vorhandenen Schlüssels aus der Hashmap abzurufen, aber ich befürchte, dass er trotzdem kriminell sein könnte:

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;
        }
    }

Beispiel

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

1

Bitte schauen Sie unter Punkte:

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.

0

Sie können, wenn Sie anstelle von Java native HashMap eine Bimap verwenden .
Es ist nicht die traditionelle Map-Implementierung, und Sie müssen sicherstellen, dass sie Ihren Anforderungen entspricht.

Eine Bimap (oder "bidirektionale Karte") ist eine Karte, die die Eindeutigkeit ihrer Werte sowie die ihrer Schlüssel bewahrt. Diese Einschränkung ermöglicht es Bimaps, eine "inverse Ansicht" zu unterstützen. Dies ist eine weitere Bimap, die dieselben Einträge wie diese Bimap enthält, jedoch umgekehrte Schlüssel und Werte.

Mit einer Bimap können Sie die Ansicht umkehren und den Schlüssel ersetzen.
Testen Sie sowohl Apache Commons BidiMap als auch Guava BiMap .


0

In meinem Fall hatte eine Karte nicht echten Schlüssel -> echte Schlüssel, also musste ich die nicht reellen durch die reellen in meiner Karte ersetzen (die Idee ist wie bei anderen)

getFriendlyFieldsMapping().forEach((friendlyKey, realKey) ->
    if (map.containsKey(friendlyKey))
        map.put(realKey, map.remove(friendlyKey))
);
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.