是否可以重命名 Hashmap 键?

Posted

技术标签:

【中文标题】是否可以重命名 Hashmap 键?【英文标题】:Is it possible to rename a Hashmap key? 【发布时间】:2012-06-01 18:33:48 【问题描述】:

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

【问题讨论】:

天哪,我希望不会。删除并重新输入键/值对似乎是要走的路。请注意,您通常只处理地图本身中的引用。 请不要修改哈希条目的键!如果幸运的话,您会将其更改为具有相同哈希码的内容,并且您会有点疯狂地试图弄清楚发生了什么;如果你不走运,你最终会得到一个找不到的条目(嗯,直到下一次重建整个表)。删除/重新插入要明智得多,而且应该很便宜(毕竟都是参考)。 【参考方案1】:

您不重命名哈希映射键,您必须使用新键插入新条目并删除旧条目。

【讨论】:

【参考方案2】:

尝试删除元素并使用新名称重新放置。假设您的地图中的键是String,则可以这样实现:

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

【讨论】:

+1。最简单的阅读是map.put( "newKey", map.remove( "oldKey" ) );,并提供包含oldKey 就可读性而言,我很不同意,我个人更喜欢清楚地看到一个对象从地图中删除,然后添加。由于 OP 对 Java 来说似乎很新,所以我决定这样说。然而,为了性能,您的版本当然是首选(因为我认为编译器不会以您的方式优化我的版本)。 对于javac 1.8.0_45,单行版本短了两个字节码,这让我很吃惊。更烦人的是泛型你不能将 obj 传递给 put 而不将其转换或声明为另一种类型,但当然直接传递 remove 的结果是有效的。【参考方案3】:

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

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

【讨论】:

【参考方案4】:

您无法重命名/修改 hashmap key 一旦添加。

唯一的方法是删除/移除key 并插入新的keyvalue 对。

原因:在 hashmap 内部实现中,Hashmap key 修饰符标记为 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

【讨论】:

这是我认为最好的答案,因为不可能重命名密钥。【参考方案5】:
hashMap.put("New_Key", hashMap.remove("Old_Key"));

这会做你想做的事,但是你会注意到钥匙的位置已经改变了。

【讨论】:

@Vins 请重新访问文档:D,remove() 将返回对象,检查此tutorialspoint.com/java/util/hashmap_remove.htm 我的错,我删除了我的评论并投了赞成票。对此感到抱歉。【参考方案6】:

您可以,如果您将使用 Bimap 而不是 Java 原生 HashMap。 这不是传统的 Map 实现,您需要确保它适合您的需求。

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

使用 bimap,您可以反转视图并替换键。 查看 Apache Commons BidiMap 和 Guava BiMap。

【讨论】:

【参考方案7】:

我认为 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!!!");

【讨论】:

【参考方案8】:

在我的情况下,地图包含非真实键 -> 真实键,所以我不得不用我的地图中的真实替换非真实(这个想法就像其他人一样)

getFriendlyFieldsMapping().forEach((friendlyKey, realKey) ->
    if (map.containsKey(friendlyKey))
        map.put(realKey, map.remove(friendlyKey))
);

【讨论】:

【参考方案9】:

请看以下几点:

    不,一旦添加,您就不能重命名HashMapkey

    首先你必须删除或移除那个key,然后你可以用value插入新的key

    因为在HashMap 内部实现中,HashMap 键修饰符是final

【讨论】:

以上是关于是否可以重命名 Hashmap 键?的主要内容,如果未能解决你的问题,请参考以下文章

如何优雅地重命名 Ruby 中哈希中的所有键? [复制]

笔记法F2键不能重命名

在 Xcode 中重命名或重构文件

重命名对象键[重复]

重命名返回键完成[重复]

是否可以重命名 AWS Lambda 函数?