合并多个哈希图

时间:2013-10-10 12:30:44

标签: java map merge hashmap

所以,我有两个hashMaps

public HashMap<String, Integer> map1 = new HashMap<String,Integer>();

public HashMap<String, Integer> map2 = new HashMap<String,Integer>();

我想创建一个hashmap,它包含两个合并的哈希映射。

此外,当我向这两个哈希图中的任何一个添加元素时:

map1.put("key",1);

第三个hashmap应该有这个改变

SOLUTION:

import java.util.*;
public final class JoinedMap {
static class JoinedMapView<K,V> implements Map<K,V> {
    private final Map<? extends K,? extends V>[] items;
    public JoinedMapView(final Map<? extends K,? extends V>[] items) {
        this.items = items;
    }

    @Override
    public int size() {
        int ct = 0;
        for (final Map<? extends K,? extends V> map : items) {
            ct += map.size();
        }
        return ct;
    }

    @Override
    public boolean isEmpty() {
        for (final Map<? extends K,? extends V> map : items) {
            if(map.isEmpty()) return true;
        }
        return false;
    }

    @Override
    public boolean containsKey(Object key) {
        for (final Map<? extends K,? extends V> map : items) {
            if(map.containsKey(key)) return true;
        }
        return false;
    }

    @Override
    public boolean containsValue(Object value) {
        for (final Map<? extends K,? extends V> map : items) {
            if(map.containsValue(value)) return true;
        }
        return false;
    }

    @Override
    public V get(Object key) {
        for (final Map<? extends K,? extends V> map : items) {
            if(map.containsKey(key)){
                return map.get(key);
            }
        }
        return null;
    }

    @Override
    public V put(K key, V value) {
        throw new UnsupportedOperationException();
    }

    @Override
    public V remove(Object key) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void putAll(Map<? extends K, ? extends V> m) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void clear() {
        for (final Map<? extends K,? extends V> map : items) {
            map.clear();
        }
    }

    @Override
    public Set<K> keySet() {
        Set<K> mrgSet = new HashSet<K>();
        for (final Map<? extends K,? extends V> map : items) {
            mrgSet.addAll(map.keySet());
        }
        return mrgSet;
    }

    @Override
    public Collection<V> values() {
        Collection<V> values = new ArrayList<>();
        for (final Map<? extends K,? extends V> map : items) {
            values.addAll(map.values());
        }
        return values;
    }

    @Override
    public Set<Entry<K, V>> entrySet() {
        throw new UnsupportedOperationException();
    }
}

/**
 * Returns a live aggregated map view of the maps passed in.
 * None of the above methods is thread safe (nor would there be an easy way
 * of making them).
 */
public static <K,V> Map<K,V> combine(
        final Map<? extends K, ? extends V>... items) {
    return new JoinedMapView<K,V>(items);
}

private JoinedMap() {
}
}

3 个答案:

答案 0 :(得分:1)

我认为这种方法是一个好的开始(当然你需要覆盖HashMap的删除和其他适当的方法):

class MyMergeAwareHashMap<K,V> extends HashMap<K,V> {
    HashMap<K, V> mergeMap

    public MyMergeAwareHashMap(Map<K, V> mergeMap) {
      this.mergeMap = mergeMap
    }

    @Override
    public Object put(K key, V value) {
      super.put(key, value)
      mergeMap.put(key, value)
    }
}

HashMap<String, Integer> mergedMap = new HashMap<String, Integer>()
MyMergeAwareHashMap<String, Integer> map1 = new MyMergeAwareHashMap<String, Integer>(mergedMap)
MyMergeAwareHashMap<String, Integer> map2 = new MyMergeAwareHashMap<String, Integer>(mergedMap)


map1.put('A', 1)
map2.put('B', 2)

println(map1.get('A')) // => 1
println(map1.get('B')) // => null

println(map2.get('A')) // => null
println(map2.get('B')) // => 2

println(mergedMap.get('A')) // => 1
println(mergedMap.get('B')) // => 2

答案 1 :(得分:0)

如果您不想手动更新第3张地图,则需要一个包装器,为其扩展hashmap

public class ExtHashMap<K, V> extends HashMap<K,V>{

    HashMap<K,V> map1,map2;

    public ExtHashMap(HashMap<k,V> _map1, HashMap<K,V> _map2){
       map1=_map1;
       map2=_map2;
    }

    //then override every method simulating merged map1,map2
    @Override
    public V get(Object key) { /* find in map1 or map2*/ }
}

答案 2 :(得分:0)

您可以使用一个地图并根据要阅读的地图过滤检索到的数据。 这实际上取决于您希望如何处理两个地图之间的碰撞。如果您不想碰撞,可以使用:

private Map<String, Integer> map = newHashMap<>():

void putInMap1(String key, Integer value) {
    map.put(key + "_1", value);
}

void putInMap2(String key, Integer value) {
    map.put(key + "_" + 1, value);
}

Integer getFromMap1(String key) {
     return map.get(key + "_1");
}

Integer getFromMap2(String key) {
     return map.get(key + "_2");
}

List<Integer> getFromMap3(String key) {
     List<Integer> res = new ArrayList<>();
     Integer map1Val = getFromMap1(key);
     if (map1Val != null) {
        res.add(map1Val);
     }
     Integer map2Val = getFromMap2(key);
     if (map2Val != null) {
        res.add(map2Val);
     }
     return res;
}