问题
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