Rany, mam nadzieję, że nie. Wydaje się, że najlepszym rozwiązaniem jest usunięcie i ponowne wprowadzenie pary klucz / wartość. Zauważ, że normalnie i tak obsługujesz tylko odniesienia w samej mapie.
Maarten Bodewes
4
Proszę nie modyfikować klucza wpisu hash! Jeśli masz szczęście, zmienisz to na coś z tym samym hashcode i po prostu oszalejesz, próbując dowiedzieć się, co się stało; jeśli masz pecha, skończysz z wpisem, którego nie można znaleźć (cóż, dopiero przy następnej przebudowie całej tabeli). Usunięcie / ponowne włożenie jest znacznie rozsądniejsze i powinno być dość tanie (w końcu to wszystkie odniesienia).
Donal Fellows
Odpowiedzi:
140
Spróbuj usunąć element i umieść go ponownie z nową nazwą. Zakładając, że klucze na twojej mapie są String, można to osiągnąć w ten sposób:
+1. Najłatwiejszy do odczytania jest map.put( "newKey", map.remove( "oldKey" ) );i zawieraoldKey
Ravinder Reddy
15
Jeśli chodzi o czytelność, to zupełnie się nie zgadzam, osobiście wolę wyraźnie widzieć, że obiekt jest usuwany z mapy, a następnie dodawany. A ponieważ OP wydaje się być całkiem nowy dla Javy, zdecydowałem się ująć to w ten sposób. Jednak ze względu na wydajność preferowana jest oczywiście twoja wersja (ponieważ nie sądzę, aby kompilator zoptymalizował moją wersję na twój sposób).
Alexis Pigeon
3
Dla javaca 1.8.0_45 wersja jednowierszowa jest o dwa bajty krótsza, co mnie zaskoczyło. Więcej irytująco z rodzajowych nie można przejść objdo putbez rzucania go lub deklarując je jako inny typ, ale oczywiście przechodząc wyniku removedziała bezpośrednio.
Twierdzę, że istota kluczy hasmap służy do celów dostępu do indeksów i nic więcej, ale oto hack: tworzenie klasy opakowującej klucz wokół wartości klucza, aby obiekt opakowujący klucz stał się kluczem hashmap do dostępu do indeksu, więc ty może uzyskać dostęp i zmienić wartość obiektu opakowującego klucz zgodnie z określonymi potrzebami:
Chociaż możesz również mieć nieistniejący klucz, aby uzyskać wartość istniejącego klucza z haszmapy, ale obawiam się, że może to być przestępstwo, tak czy inaczej:
publicclassKeyWrapper<T>{
private T key;
publicKeyWrapper(T key){
this.key=key;
}
@Overridepublicbooleanequals(Object o){
return hashCode()==o.hashCode();
}
@OverridepublicinthashCode(){
int hash=((String)key).length();//however you want your hash to be computed such that two different objects may share the same at some pointreturn hash;
}
}
Przykład
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!!!");
Możesz, jeśli zamiast natywnej Java HashMap użyjesz Bimap .
To nie jest tradycyjna implementacja Map i musisz się upewnić, że odpowiada Twoim potrzebom.
Bimapa (lub „mapa dwukierunkowa”) to mapa, która zachowuje niepowtarzalność swoich wartości, a także kluczy. To ograniczenie umożliwia elementom bimap obsługę „widoku odwróconego”, czyli kolejnej bimapy zawierającej te same wpisy co ta bimapa, ale z odwróconymi kluczami i wartościami.
Używając bimap, możesz odwrócić widok i zamienić klucz. Sprawdź
zarówno Apache Commons BidiMap, jak i Guava BiMap .
W moim przypadku miałem mapę zawierającą nie prawdziwy klucz -> prawdziwe klucze, więc musiałem zamienić nie rzeczywiste na rzeczywiste w mojej mapie (pomysł jest jak inne)
getFriendlyFieldsMapping().forEach((friendlyKey, realKey) ->
if (map.containsKey(friendlyKey))
map.put(realKey, map.remove(friendlyKey))
);
Odpowiedzi:
Spróbuj usunąć element i umieść go ponownie z nową nazwą. Zakładając, że klucze na twojej mapie są
String
, można to osiągnąć w ten sposób:Object obj = map.remove("oldKey"); map.put("newKey", obj);
źródło
map.put( "newKey", map.remove( "oldKey" ) );
i zawieraoldKey
obj
doput
bez rzucania go lub deklarując je jako inny typ, ale oczywiście przechodząc wynikuremove
działa bezpośrednio.hashMap.put("New_Key", hashMap.remove("Old_Key"));
Zrobi to, co chcesz, ale zauważysz, że lokalizacja klucza się zmieniła.
źródło
Przypisz wartość klucza, którego nazwę należy zmienić, do nowego klucza. I wyjmij stary klucz.
hashMap.put("New_Key", hashMap.get("Old_Key")); hashMap.remove("Old_Key");
źródło
key
Po dodaniu nie można zmienić nazwy ani zmodyfikować mapy hasma .Jedynym sposobem jest usunięcie / usunięcie
key
i włożenie nowegokey
ivalue
parowania.Powód : w wewnętrznej implementacji hashmap
key
modyfikatorHashmapoznaczony jakofinal
.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 }
Dla odniesienia: HashMap
źródło
Nie zmieniasz nazwy klucza hashmap, musisz wstawić nowy wpis z nowym kluczem i usunąć stary.
źródło
Twierdzę, że istota kluczy hasmap służy do celów dostępu do indeksów i nic więcej, ale oto hack: tworzenie klasy opakowującej klucz wokół wartości klucza, aby obiekt opakowujący klucz stał się kluczem hashmap do dostępu do indeksu, więc ty może uzyskać dostęp i zmienić wartość obiektu opakowującego klucz zgodnie z określonymi potrzebami:
public class KeyWrapper<T>{ private T key; public KeyWrapper(T key){ this.key=key; } public void rename(T newkey){ this.key=newkey; } }
Przykład
HashMap<KeyWrapper,String> hashmap=new HashMap<>(); KeyWrapper key=new KeyWrapper("cool-key"); hashmap.put(key,"value"); key.rename("cool-key-renamed");
Chociaż możesz również mieć nieistniejący klucz, aby uzyskać wartość istniejącego klucza z haszmapy, ale obawiam się, że może to być przestępstwo, tak czy inaczej:
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; } }
Przykład
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!!!");
źródło
Proszę spojrzeć poniżej punktów:
Nie, nie można zmienić nazwy
key
odHashMap
razu dodaje.Najpierw musisz to usunąć lub usunąć,
key
a następnie możesz wstawić nowy zakey
pomocąvalue
.Ponieważ w
HashMap
implementacji wewnętrznejHashMap
kluczowym modyfikatorem jestfinal
.źródło
Możesz, jeśli zamiast natywnej Java HashMap użyjesz Bimap .
To nie jest tradycyjna implementacja Map i musisz się upewnić, że odpowiada Twoim potrzebom.
Używając bimap, możesz odwrócić widok i zamienić klucz. Sprawdź
zarówno Apache Commons BidiMap, jak i Guava BiMap .
źródło
W moim przypadku miałem mapę zawierającą nie prawdziwy klucz -> prawdziwe klucze, więc musiałem zamienić nie rzeczywiste na rzeczywiste w mojej mapie (pomysł jest jak inne)
getFriendlyFieldsMapping().forEach((friendlyKey, realKey) -> if (map.containsKey(friendlyKey)) map.put(realKey, map.remove(friendlyKey)) );
źródło