2016-03-26 15 views
8

trzeba połączyć n hashmaps usytuowany w pętli, jak pokazano poniżej na javy 8 połączenia lub coś:Jak stosować Java 8 funkcję scalania przez liczbę n hashmaps

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

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

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

chciałbym uzyskać wyjście jak poniżej:

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

Kiedy próbuję użyć putall jak ten

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

Jeżeli wartość duplikatu klucza jest "", poprzednia wartość zostanie zastąpiona nową. Muszę łączyć wartości, zamiast je zastępować.

+1

Co '123/456/789' oznacza? Czy chcesz uzyskać "Map >"? – Tunaki

+0

wystarczy podać wartości ... przepraszam za brak jasności ... – nelz

+2

Wygląda na to, że powinieneś używać niestandardowej klasy z 3 polami 'name',' phone' i 'work' zamiast' HashMap'. –

Odpowiedz

9

Jeśli masz List<Map<String, String>>, która reprezentuje listę map do łączenia, można mieć

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

ten płaski mapy każdej mapie w strumień swoich wpisów. Następnie strumień jest pogrupowany według wartości każdego wpisu i wszystkie odrębne elementy z tym samym kluczem są odwzorowane na ich wartość, połączone.

Odrębna część jest możliwa dzięki zebraniu wszystkich wartości wewnątrz Set.


Przykładowy kod:

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 ... Wielkie dzięki ... pozwól mi spróbować wdrożyć to w ten sposób! – nelz

+0

działa jak urok ..... dzięki bardzo .... – nelz