2013-10-10 2 views
1

Итак, у меня есть два HashMapsОбъединение нескольких HashMaps

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

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

Я хочу создать HashMap, который состоит из обоих этих HashMaps слиты.

Кроме того, когда я добавить элемент в любой из этих 2 HashMaps:

map1.put("key",1); 

Третий HashMap должны иметь это изменение

РЕШЕНИЕ:

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

@andras Это не точный дубликат. Проблема здесь другая. Пожалуйста, внимательно прочитайте вопрос, прежде чем закрывать его как дубликат. –

+1

Я хочу, чтобы третья карта имела какие-то изменения, которые я делаю на первых двух картах. Это не сделало бы этого – arxenix

+0

извините, не заметил дополнительных требований. разъяснение помогает. – andras

ответ

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 
+0

Странно, что это не работает в groovy web console больше, но работает, когда я запускаю его локально. – heikkim

+0

Спасибо! Это простой способ сделать это :) – arxenix

0

, если вы не хотите, чтобы вручную обновить 3rd карты, вам нужна обертка, расширяя 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*/ } 
} 
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; 
} 
Смежные вопросы