是否可以重命名Hashmap密钥?


89

我正在寻找一种重命名Hashmap密钥的方法,但是我不知道在Java中是否可行。


11
天哪,我希望不会。删除并重新输入键/值对似乎是可行的方法。请注意,无论如何,您通常通常只处理地图本身中的引用。
Maarten Bodewes,2012年

4
请不要修改哈希条目的键!如果幸运的话,您可以将其更改为具有相同哈希码的内容,并且会疯狂地尝试找出发生了什么。如果您不走运,您将得到一个找不到的条目(嗯,直到下一次重新构建整个表时)。删除/重新插入要好得多,并且应该很便宜(毕竟是所有引用)。
Donal Fellows

Answers:


137

尝试删除该元素,然后使用新名称再次放置它。假设地图中的键是String,则可以通过以下方式实现:

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

59
+1。而最简单的读的是map.put( "newKey", map.remove( "oldKey" ) );并提供了包含oldKey
雷文德·雷迪

15
就可读性而言,我完全不同意,我个人更希望清楚地看到从地图上删除了一个对象,然后又添加了一个对象。而且由于OP对Java来说似乎还很陌生,所以我决定采用这种方式。但是出于性能方面的考虑,当然最好选择您的版本(因为我认为编译器不会以您的方式优化我的版本)。
亚历克西斯·皮金

3
对于Javac 1.8.0_45,单行版本短两个字节码,这让我感到惊讶。更令人讨厌的是,使用泛型时,您不能不进行强制转换或将其声明为另一种类型而传递objput它,但是当然可以传递remove直接结果。
塞缪尔·埃德温·沃德2015年

1
但是如何重命名所有密钥
gstackoverflow

4
它将导致ConcurrentModificationException
gstackoverflow

19

将需要重命名的密钥值分配给新密钥。并删除旧密钥。

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


9

您不能重命名/修改哈希映射

唯一的方法是删除/删除键,并插入新的键和值对。

原因:在hashmap内部实现中,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键的本质是用于索引访问,仅此而已,这是一个hack:围绕键的值创建一个key-wrapper类,以便key-wrapper对象成为用于索引访问的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) 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

如果不是Java本机的HashMap,您可以使用Bimap
它不是传统的Map实现,因此您需要确保它适合您的需求。

双图(或“双向图”)是保留其值和键的唯一性的图。此约束使bimap可以支持“反向视图”,这是另一个bimap,它包含与此bimap相同的条目,但具有相反的键和值。

使用bimap,可以反转视图并替换关键点。
检出Apache Commons BidiMap和Guava BiMap


0

在我的情况下,地图包含非实键->实键,因此我不得不用地图中的实数替换非实数(这个想法与其他想法一样)

getFriendlyFieldsMapping().forEach((friendlyKey, realKey) ->
    if (map.containsKey(friendlyKey))
        map.put(realKey, map.remove(friendlyKey))
);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.