Чи можна перейменувати ключ Hashmap?


92

Я шукаю спосіб перейменувати ключ Hashmap, але я не знаю, чи можливо це в Java.


11
Боже, сподіваюсь, ні. Видалення та повторне введення пари ключ / значення здається правильним шляхом. Зверніть увагу, що ви, як правило, просто обробляєте посилання на самій карті.
Маартен Бодеус

4
Будь ласка, не модифікуйте ключ хеш-запису! Якщо вам пощастить, ви зміните його на щось із тим самим хеш-кодом, і ви просто зійдете з розуму, намагаючись зрозуміти, що сталося; якщо вам не пощастить, ви отримаєте запис, якого неможливо знайти (ну, лише до наступної перебудови всієї таблиці). Видалити / повторно вставити набагато розумніше і має бути досить дешевим (врешті-решт, це всі посилання).
Donal Fellows

Відповіді:


140

Спробуйте видалити елемент і знову поставити його з новою назвою. Якщо припустити, що ключі на вашій карті є String, це можна досягти таким чином:

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

61
+1. І найпростіший для читання є map.put( "newKey", map.remove( "oldKey" ) );і надається міститьoldKey
Ravinder Reddy

15
Що стосується читабельності, то я абсолютно не погоджуюсь, я особисто вважаю за краще чітко бачити, що об'єкт видаляється з карти, а потім додається. І оскільки OP здається досить новим для Java, я вирішив сформулювати це так. Однак для підвищення продуктивності, ваша версія, звичайно, є кращою (оскільки я не думаю, що компілятор оптимізує мою версію по-вашому).
Alexis Pigeon

3
Для javac 1.8.0_45 однорядкова версія на два байт-коди коротша, що мене здивувало. Більш дратівливо дженериків ви не можете пройти , objщоб putбез приведення його або оголосити його в якості іншого типу, але, звичайно , передаючи результат з removeбезпосередньо працює.
Семюель Едвін Уорд

1
Але як перейменувати всі ключі
gstackoverflow

4
Це призведе до ConcurrentModificationException
gstackoverflow

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

Це зробить те, що ви хочете, але ви помітите, що розташування ключа змінилося.


@Vins перегляньте документацію, будь ласка: D, remove () поверне об'єкт, перевірте це tutorialspoint.com/java/util/hashmap_remove.htm
Мохамед Закарія Ель-Зогбі

1
погано, я видалив свій коментар і проголосував за нього. Вибач за те.
Вінс

19

Призначте значення ключа, який потрібно перейменувати, до нового ключа. І вийміть старий ключ.

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

10

Ви не можете перейменовувати / змінювати хеш-карту keyпісля додавання.

Єдиний спосіб - це видалити / видалити keyта вставити разом із новими keyта valueпарами.

Причина : У внутрішній реалізації hashmapkeyмодифікаторHashmapпозначений як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
}

Для довідки: HashMap


це найкраща відповідь на мій погляд , так як це НЕ можливо перейменувати ключ.
Вольфсон

4

Ви не перейменовуєте ключ хеш-карти, вам потрібно вставити новий запис за допомогою нового ключа і видалити старий.


2

Я б стверджував, що суть ключів hasmap в цілях доступу до індексу і не більше, але ось хак: створення класу обгортки ключів навколо значення ключа, щоб об'єкт обгортки ключів став ключем hashmap для доступу до індексу, так що ви може отримувати доступ та змінювати значення об’єкта-обгортки ключів відповідно до ваших конкретних потреб:

public class KeyWrapper<T>{

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

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

}

Приклад

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

Хоча у вас також може бути неіснуючий ключ, який зможе отримати значення існуючого ключа з хеш-карти, але я боюся, що це може бути злочинним способом:

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

Приклад

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

Будь ласка, подивіться нижче пункти:

  1. Ні, Ви не можете перейменувати keyз HashMapколи - то додав.

  2. Спочатку вам потрібно видалити або видалити це, keyа потім ви можете вставити з новим за keyдопомогою value.

  3. Оскільки у HashMapвнутрішній реалізації HashMapключовим модифікатором є final.


0

Ви можете, якщо замість рідної HashMap на Java ви будете використовувати Bimap .
Це не традиційна реалізація Map, і вам потрібно переконатися, що вона відповідає вашим потребам.

Бімапа (або "двонаправлена ​​карта") - це карта, яка зберігає унікальність своїх значень, а також своїх ключів. Це обмеження дозволяє бімапам підтримувати "зворотний вигляд", який є іншим бімапом, що містить ті самі записи, що і цей бімап, але зі зворотними ключами та значеннями.

Використовуючи бімап, ви можете перевернути вигляд і замінити ключ. Оформіть
як Apache Commons BidiMap, так і Guava BiMap .


0

У моєму випадку була карта, що містить не справжній ключ -> реальні ключі, тому мені довелося замінити не реальні на реальні на моїй карті (ідея схожа на інші)

getFriendlyFieldsMapping().forEach((friendlyKey, realKey) ->
    if (map.containsKey(friendlyKey))
        map.put(realKey, map.remove(friendlyKey))
);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.