Merging multiple hashmaps

邮差的信 提交于 2019-12-13 19:13:00

问题


So, i have two hashMaps

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

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

I want to create a hashmap, which consists of both of these hashmaps merged.

Also, when I add an element to either of these 2 hashmaps:

map1.put("key",1);

The third hashmap should have this change

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() {
}
}

回答1:


I think this kind of approach is a good start (of course you would need to override HashMap's remove and other appropriate methods):

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



回答2:


if you don't want to manually update your 3rd map, you need a wrapper, extending hashmap for it

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*/ }
}



回答3:


You can use one map and filter the retrieved data based on the map you want to read from. It really depends on how you want to treat collisions between two maps. If you want no collisions you can use:

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;
}


来源:https://stackoverflow.com/questions/19295801/merging-multiple-hashmaps

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!