Czy można zmienić nazwę klucza Hashmap?

92

Szukam sposobu na zmianę nazwy klucza Hashmap, ale nie wiem, czy jest to możliwe w Javie.

Ikes
źródło
11
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:

Object obj = map.remove("oldKey");
map.put("newKey", obj);
Alexis Pigeon
źródło
61
+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.
Samuel Edwin Ward
1
Ale jak zmienić nazwy wszystkich kluczy
gstackoverflow
4
Doprowadzi to do
wyjątku
20
hashMap.put("New_Key", hashMap.remove("Old_Key"));

Zrobi to, co chcesz, ale zauważysz, że lokalizacja klucza się zmieniła.

Mohamed Zakaria El-Zoghbi
źródło
@Vins ponownie zajrzyj do dokumentacji: D, remove () zwróci obiekt, sprawdź ten tutorialspoint.com/java/util/hashmap_remove.htm
Mohamed Zakaria El-Zoghbi
1
mój błąd, usunąłem swój komentarz i zagłosowałem na niego. Przepraszam za to.
Vins
19

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");
Deepak Mani
źródło
10

keyPo dodaniu nie można zmienić nazwy ani zmodyfikować mapy hasma .

Jedynym sposobem jest usunięcie / usunięcie keyi włożenie nowego keyi valueparowania.

Powód : w wewnętrznej implementacji hashmapkeymodyfikatorHashmapoznaczony 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

Jasny promień
źródło
to jest moim zdaniem najlepsza odpowiedź, ponieważ zmiana nazwy klucza nie jest możliwa.
Wolfson
4

Nie zmieniasz nazwy klucza hashmap, musisz wstawić nowy wpis z nowym kluczem i usunąć stary.

Hari Menon
źródło
2

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!!!");
LiNKeR
źródło
1

Proszę spojrzeć poniżej punktów:

  1. Nie, nie można zmienić nazwy keyod HashMaprazu dodaje.

  2. Najpierw musisz to usunąć lub usunąć, keya następnie możesz wstawić nowy za keypomocą value.

  3. Ponieważ w HashMapimplementacji wewnętrznej HashMapkluczowym modyfikatorem jest final.

Ghanshyam
źródło
0

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 .

dorony
źródło
0

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))
);
Basheer AL-MOMANI
źródło