HashMap中的1对1映射

时间:2013-01-18 14:33:41

标签: java hashmap

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

HashMap<Key, Path>

最初我为每个目录Key创建Path并将这些条目放在HashMap中。处理时,我会根据Path中的KeyHashMap并处理它们。在某些情况下,我会针对某些Key重新计算Path,并希望将新Key替换为Key的新Path。我希望为唯一路径保留唯一的密钥,并使用其中一个更新HashMap中的Entry。所以我想执行HashMap的反向更新Key。什么是最好的技术?

先谢谢。

7 个答案:

答案 0 :(得分:5)

您可能正在寻找 Google Guava的 BiMap

  

bimap(或“双向地图”)是保留地图的地图   其价值的独特性以及其价值的独特性。这个约束   使bimaps支持“逆视图”,这是另一个bimap   包含与此bimap相同的条目,但使用反向键和   值。

答案 1 :(得分:3)

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

答案 2 :(得分:1)

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

   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");

答案 3 :(得分:0)

我会

myHashMap.remove(Key);

然后

myHashMap.put( newKey, new value);

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

答案 4 :(得分:0)

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

hm.set(newKey, oldPath);

其中hm是您的HashMap。然后,使用

hm.remove(oldKey)

删除旧密钥。

请注意,如果您可能有两个Path具有相同的Key,那么您必须将HashMap转换为<Path, Key>,因为一个Key {{1}} 1}}会覆盖另一个。要查找值并检索其密钥use the entrySet() and loop through (update 1 to the linked post)

希望这有帮助!

答案 5 :(得分:0)

假设双向散列保证为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);
    }

}

答案 6 :(得分:0)

最近需要一个解决方案,但不想依赖插件,所以我扩展了基础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);
        }
    }
}