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

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

【问题讨论】:

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

标签: java hashmap


【解决方案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"));
      

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

      【讨论】:

      【解决方案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】:

            请看以下几点:

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

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

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

            【讨论】:

              猜你喜欢
              • 2022-12-02
              • 2013-02-22
              • 2020-07-04
              • 1970-01-01
              • 2023-04-10
              • 2015-03-05
              • 2021-01-08
              • 2010-11-23
              相关资源
              最近更新 更多