Java HashMap中的1对1映射

Java HashMap中的1对1映射,java,hashmap,Java,Hashmap,我遇到的情况是,我将根据HashMap中的值更改键。我的HashMap是: HashMap<Key, Path> HashMap 最初,我为每个目录创建键s路径,并将这些条目放入HashMap。在进行处理时,我将根据Key从HashMap获取Path并对其进行处理。在某些情况下,我将重新计算某些路径的键,并希望用新的键替换该路径的键。我想为唯一路径保留唯一键,并用其中一个更新HashMap中的条目。所以我想执行HashMap的反向操作来更新密钥。这方面最好的技术是什么 提前感谢。

我遇到的情况是,我将根据
HashMap
中的值更改键。我的
HashMap
是:

HashMap<Key, Path>
HashMap
最初,我为每个目录创建
s
路径
,并将这些条目放入
HashMap
。在进行处理时,我将根据
Key
HashMap
获取
Path
并对其进行处理。在某些情况下,我将重新计算某些路径的
,并希望用新的
键替换该路径的
键。我想为唯一路径保留唯一键,并用其中一个更新HashMap中的条目。所以我想执行HashMap的反向操作来更新密钥。这方面最好的技术是什么


提前感谢。

添加另一个HashMap来执行反向映射。与原始地图保持同步,就这样。我甚至会创建一个helper类,以确保所有操作在两个映射之间同步。

如果要更新密钥,可以执行以下操作:

   String oldKey = "oldKey";
   String newKey = "newKey";

   map.put(newKey, map.remove(oldKey));
要基于值获取密钥,您可以使用:

  • 比迪地图->
  • 或者维护两个映射,一个以值为键,另一个以键为键

为了好玩,下面介绍了如何维护两个地图:

    Map<String, String> keyMap = new HashMap<String, String>();
    Map<String, String> valueMap = new HashMap<String, String>();

    String val = "someVal";
    keyMap.put("newKey", keyMap.remove(valueMap.get(val)));
    valueMap.put(val, "newKey");
Map keyMap=newhashmap();
Map valueMap=新的HashMap();
字符串val=“someVal”;
keyMap.put(“newKey”,keyMap.remove(valueMap.get(val));
valueMap.put(val,“newKey”);
我会的

myHashMap.remove(Key);
然后


在hashMap的迭代过程中,删除选项是不允许的。

可能是您正在寻找谷歌番石榴

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


如果要设置新密钥,请使用

hm.set(newKey, oldPath);
其中
hm
是您的
HashMap
。然后,使用

hm.remove(oldKey)
取下旧钥匙

请注意,如果可能有两个
路径
具有相同的
,则必须将
哈希映射
反转为
,因为一个
键会覆盖另一个。要查找值并检索其键,请执行以下操作


希望这有帮助

假设双向散列保证为1对1,并且不考虑内存使用,这是一个纯java解决方案

public class BiHash<K> extends ConcurrentHashMap<K, K>  {

    public void biPut(K k1, K k2)
    {
        super.put(k1, k2);
        super.put(k2, k1);
    }

}
公共类BiHash扩展了ConcurrentHashMap{
公共空位biPut(kk1,kk2)
{
超级put(k1,k2);
超级put(k2,k1);
}
}

最近需要一个解决方案,但不想依赖插件,所以我扩展了基本Java类。此实现不允许空值

public class OneToOneMap<K,V> extends HashMap<K,V> {
    public OneToOneMap() {
        super();
    }
    public OneToOneMap(int initialCapacity) {
        super(initialCapacity);
    }
    public OneToOneMap(int initialCapacity, float loadFactor) {
        super(initialCapacity, loadFactor);
    }
    public OneToOneMap(Map<? extends K, ? extends V> m) {
        super(m);
        dedup();
    }

    @Override
    public void putAll(Map<? extends K, ? extends V> m){
        super.putAll(m);
        dedup();
    }

    @Override
    public V put(K key, V value) {
        if( key == null || value == null ) return null;
        removeValue(value);
        return super.put(key,value);
    }

    public K getKey( V value ){
        if( value == null || this.size() == 0 ) return null;
        Set<K> keys = new HashSet<>();
        keys.addAll(keySet());
        for( K key : keys ){
            if( value.equals(get(key) )) return key;
        }
        return null;
    }
    public boolean hasValue( V value ){
        return getKey(value) != null;
    }
    public boolean hasKey( K key ){
        return get(key) != null;
    }

    public void removeValue( V remove ){
        V value;
        Set<K> keys = new HashSet<>();
        keys.addAll(keySet());
        for( K key : keys ){
            value = get(key);
            if( value == null || key == null || value.equals(remove)) remove(key);
        }        
    }
    //can be used when a new map is assigned to clean it up
    public void dedup(){
        V value;
        Set<V> values = new HashSet<>();
        Set<K> keys = new HashSet<>();
        keys.addAll(keySet());
        for( K key : keys ){
            value = get(key);
            if( value == null || key == null || values.contains(value) ) remove(key);
            else values.add(value);
        }
    }
}
公共类OneToOneMap扩展了HashMap{
公共OneToneMap(){
超级();
}
公共OneToOneMap(初始容量){
超级(初始容量);
}
公共OneToOneMap(初始容量、浮动负载系数){
超级(初始容量、负载系数);
}

公共网络地图MapYou可以用一个新的键添加一个新的条目,删除旧的条目。但是如果你发现你需要改变键,也许HashMap不是一个理想的结构。考虑添加谷歌Guava库并使用双类映射:我如何高效地获得基于价值的旧密钥?value@Cowls是的,谢谢,是的,我正在寻找双向地图,这将有助于伟大的人,我会考虑这个…你是冠军,这就是我正在寻找你的链接是谷歌收藏,这已经被拖了好几年了。链接可能更有用。没有必要在你的答案个人的咆哮。只要坚持事实。同时,我已经编辑了你。r答案是更专业。
public class OneToOneMap<K,V> extends HashMap<K,V> {
    public OneToOneMap() {
        super();
    }
    public OneToOneMap(int initialCapacity) {
        super(initialCapacity);
    }
    public OneToOneMap(int initialCapacity, float loadFactor) {
        super(initialCapacity, loadFactor);
    }
    public OneToOneMap(Map<? extends K, ? extends V> m) {
        super(m);
        dedup();
    }

    @Override
    public void putAll(Map<? extends K, ? extends V> m){
        super.putAll(m);
        dedup();
    }

    @Override
    public V put(K key, V value) {
        if( key == null || value == null ) return null;
        removeValue(value);
        return super.put(key,value);
    }

    public K getKey( V value ){
        if( value == null || this.size() == 0 ) return null;
        Set<K> keys = new HashSet<>();
        keys.addAll(keySet());
        for( K key : keys ){
            if( value.equals(get(key) )) return key;
        }
        return null;
    }
    public boolean hasValue( V value ){
        return getKey(value) != null;
    }
    public boolean hasKey( K key ){
        return get(key) != null;
    }

    public void removeValue( V remove ){
        V value;
        Set<K> keys = new HashSet<>();
        keys.addAll(keySet());
        for( K key : keys ){
            value = get(key);
            if( value == null || key == null || value.equals(remove)) remove(key);
        }        
    }
    //can be used when a new map is assigned to clean it up
    public void dedup(){
        V value;
        Set<V> values = new HashSet<>();
        Set<K> keys = new HashSet<>();
        keys.addAll(keySet());
        for( K key : keys ){
            value = get(key);
            if( value == null || key == null || values.contains(value) ) remove(key);
            else values.add(value);
        }
    }
}