2016-03-26 12 views
8

ho bisogno di unire n HashMaps ideale in un ciclo come mostrato di seguito utilizzando Java 8 unione o qualcosa:come usare Java 8 funzione di unione per il numero n di HashMaps

Mappa 1: {Name:XXX,Phn:123,Work:""}

Mappa 2: {Name:XXX,Phn:456,Work: xyz}

Mappa 3: {Name:XXX,Phn:789,Work:""}

vorrei ottenere un output come di seguito:

{ 
    Name:XXX,  // if all values for a key are same take one 
    Phn:123/456/789 // merge all non null values for same key 
    Work:xyz   // make sure non-null values are never replaced 
} 

quando provo ad usare putAll come questo

public Map<String,String> mergeOriginalDataMaps(List<Integer> indexList, List<Map<String,String>> originalData) { 
    Map<String,String> tmpMap = new HashMap<String,String>(); 
    for (int index : indexList) { 
     tmpMap.putAll(originalData.get(index)); 
    } 
    return tmpMap; 
} 

Se il valore della chiave duplicata è "", il valore precedente viene sostituito con quello nuovo. Ho bisogno di concatenare i valori piuttosto che sostituirli.

+1

Cosa '123/456/789' significa? Vuoi un 'Map >' come risultato? – Tunaki

+0

solo bisogno di concatenare i valori ... mi dispiace per non essere chiaro ... – nelz

+2

Sembra che dovresti usare una classe personalizzata con 3 campi 'nome',' telefono' e 'lavoro' piuttosto che un' HashMap'. –

risposta

9

Se si dispone di un List<Map<String, String>>, che rappresenta un elenco di mappe per unire, si può avere

Map<String, String> result = 
    maps.stream() 
     .flatMap(m -> m.entrySet().stream()) 
     .collect(Collectors.groupingBy(
      Map.Entry::getKey, 
      Collectors.mapping(
       Map.Entry::getValue, 
       Collectors.collectingAndThen(Collectors.<String>toSet(), s -> String.join("", s)) 
      ) 
     )); 

questo appartamento mappe ogni mappa in un flusso delle sue voci. Quindi il flusso viene raggruppato in base al valore di ciascuna voce e tutti gli elementi distinti con la stessa chiave vengono associati al loro valore, uniti.

La parte distinta è resa possibile dalla prima raccolta di tutti i valori all'interno di uno Set.


codice di esempio:

public static void main(String[] args) { 
    List<Map<String, String>> maps = new ArrayList<>(); 
    maps.add(new HashMap<String, String>(){{ put("Name", "XXX"); put("Phn", "123"); put("Work", ""); }}); 
    maps.add(new HashMap<String, String>(){{ put("Name", "XXX"); put("Phn", "456"); put("Work", "xyz"); }}); 
    maps.add(new HashMap<String, String>(){{ put("Name", "XXX"); put("Phn", "789"); put("Work", ""); }}); 

    Map<String, String> result = 
     maps.stream() 
      .flatMap(m -> m.entrySet().stream()) 
      .collect(Collectors.groupingBy(
       Map.Entry::getKey, 
       Collectors.mapping(
        Map.Entry::getValue, 
        Collectors.collectingAndThen(Collectors.<String>toSet(), s -> String.join("", s)) 
       ) 
      )); 

    System.out.println(result); // prints "{Phn=123456789, Work=xyz, Name=XXX}" 
} 
+0

WOW ... Grazie mille ... fammi provare a implementarlo in questo modo !! – nelz

+0

funziona come un incanto ..... grazie mille .... – nelz

Problemi correlati