是否可以重命名 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
并插入新的key
和value
对。
原因:在 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】:请看以下几点:
不,一旦添加,您就不能重命名HashMap
的key
。
首先你必须删除或移除那个key
,然后你可以用value
插入新的key
。
因为在HashMap
内部实现中,HashMap
键修饰符是final
。
【讨论】:
以上是关于是否可以重命名 Hashmap 键?的主要内容,如果未能解决你的问题,请参考以下文章