0

我遇到了一种情况,我将根据HashMap. 我HashMap的是:

HashMap<Key, Path>

最初我Key为每个目录创建 sPath并将这些条目放入HashMap. 在进行处理时,我会Path根据KeyfromHashMap进行处理。在某些情况下,我会重新计算Key一些Path,并想Key用新Key的替换旧的Path。我想为唯一路径保留唯一键,并使用其中一个更新 HashMap 中的条目。所以我想执行 HashMap 的反向来更新 Key。什么是最好的技术?

提前致谢。

4

7 回答 7

5

可能是您正在寻找Google Guava 的 BiMap.

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

于 2013-01-18T14:37:53.387 回答
3

添加另一个 HashMap 来进行反向映射。使其与原始地图保持同步,仅此而已。我什至会创建一个帮助类来确保所有操作在两个映射之间同步。

于 2013-01-18T14:35:18.430 回答
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");

于 2013-01-18T14:36:24.167 回答
0

我会

myHashMap.remove(Key);

然后

myHashMap.put( newKey, new value);

在 hashMap 的迭代期间,不允许删除选项。

于 2013-01-18T14:37:32.607 回答
0

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

hm.set(newKey, oldPath);

hm你在哪里HashMap。然后,使用

hm.remove(oldKey)

删除旧密钥。

请注意,如果您可能有两个Path相同的 s Key,那么您必须反转您的HashMapto <Path, Key>,因为一个Key会覆盖另一个。要查找一个值并检索其键,请使用entrySet()and 循环 (update 1 to the linked post)

希望这可以帮助!

于 2013-01-18T14:40:10.323 回答
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);
    }

}
于 2015-07-01T19:01:58.113 回答
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);
        }
    }
}
于 2017-10-28T22:53:51.077 回答