Ich suche nach einer Möglichkeit, einen Hashmap-Schlüssel umzubenennen, aber ich weiß nicht, ob dies in Java möglich ist.
Ich suche nach einer Möglichkeit, einen Hashmap-Schlüssel umzubenennen, aber ich weiß nicht, ob dies in Java möglich ist.
Antworten:
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);
map.put( "newKey", map.remove( "oldKey" ) );
und zur Verfügung gestellt enthältoldKey
obj
, put
ohne sie zu gießen oder als einen anderen Typ zu deklarieren, aber natürlich das Ergebnis von remove
direkt funktioniert.
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");
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.
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
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.
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!!!");
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 .
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))
);