2015-10-12 8 views
5

Esistono due mappe e sto cercando di unirle in una singola mappa (finalResp).Unione di mappa e valore di modifica

Map<String, String[]> map1 = new HashMap<>(); 
Map<String, String> map2 = new HashMap<>(); 

HashMap<String, String> finalResp = new HashMap<String, String>(); 

Solution - pre Java 8 - raggiunto come di seguito:

for (Map.Entry<String, String[]> entry : map1.entrySet()) { 
    if (map2.containsKey(entry.getKey())) { 
     String newValue = changetoAnother(map1.get(entry.getKey()), map2.get(entry.getKey())); 
     finalResp.put(entry.getKey(), newValue); 
    } 
} 

Utilizzo di Java 8, mi sono bloccato in questo:

HashMap<String, String> map3 = new HashMap<>(map2); 
map1.forEach((k, v) -> map3.merge(k, v, (i, j) -> mergeValue(i, j))); 

Come posso verificare se una chiave mappa 2 non è presente nella mappa 1 e modifica i valori?

risposta

4

Un modo possibile è quello di filtrare gli elementi indesiderati (non contenute nel map2) e raccogliere il risultato in una nuova mappa:

Map<String, String> finalResp = 
    map1.entrySet().stream().filter(e -> map2.containsKey(e.getKey())) 
          .collect(Collectors.toMap(
           Entry::getKey, 
           e -> changetoAnother(e.getValue(), map2.get(e.getKey())) 
          )); 

Un altro modo sarebbe quello di creare una copia di map2, mantenere tutte le chiavi di questo Map che sono anche contenute nelle chiavi map1 e infine sostituire tutti i valori applicando la funzione changetoAnother.

Map<String, String> result = new HashMap<>(map2); 
result.keySet().retainAll(map1.keySet()); 
result.replaceAll((k, v) -> changetoAnother(map1.get(k), v)); 

Nota che il vantaggio della prima soluzione è che può essere facilmente generalizzato a lavorare per le due mappe:

private <K, V, V1, V2> Map<K, V> merge(Map<K, V1> map1, Map<K, V2> map2, BiFunction<V1, V2, V> mergeFunction) { 
    return map1.entrySet().stream() 
          .filter(e -> map2.containsKey(e.getKey())) 
          .collect(Collectors.toMap(
           Entry::getKey, 
           e -> mergeFunction.apply(e.getValue(), map2.get(e.getKey())) 
         )); 
} 

con

Map<String, String> finalResp = merge(map1, map2, (v1, v2) -> changetoAnother(v1, v2)); 
+0

Grande! Grazie, comunque quando uso il mio codice, sto, ricevendo un avviso del compilatore "La variabile locale map2 definita in un ambito che la racchiude deve essere definitiva o effettivamente definitiva". Nel mio codice sto ottenendo il valore di map2 in questo modo, Map map2 = getRespItemMap (response); – Umar

+0

Dopo aver utilizzato l'approccio generalizzato, l'errore è scomparso. finalResp = unione (map1, map2, (v1, v2) -> changeto Un altro (v1, v2)); – Umar