2014-05-09 26 views
14

Mam dwa obiekty List<Map<String, Object>>.Dołącza do Java 8 Collection API

[{Month=August-2013, Sales=282200}, {Month=July-2013, Sales=310400}, 
{Month=June-2013, Sales=309600}, {Month=May-2013, Sales=318200}, 
{Month=September-2013, Sales=257800}] 

i

[{Month=April-2013, NoOfTranx=8600}, {Month=August-2013, NoOfTranx=6700}, 
{Month=July-2013, NoOfTranx=14400}, {Month=June-2013, NoOfTranx=8500}, 
{Month=May-2013, NoOfTranx=14400}] 

Chcę join(Merge) te dwa listy na Month klucza. Jak mogę wykonać kilka operacji łączenia (na przykład FULL OUTER JOIN, RIGHT OUTER JOIN itp.) Na tych listach przy użyciu nowej kolekcji API.

Odpowiedz

7

Jednym ze sposobów, aby wykonać pełne sprzężenie zewnętrzne jest najpierw skonstruować Map<String, Map<String, Object>> który łączy wartość miesięcznej na mapach siebie i uzyskać wartości z listy:

//first concatenate the two lists 
Map<String, Map<String, Object>> result = Stream.concat(list1.stream(), 
                 list2.stream()) 
       //then collect in a map where the key is the value of the month 
       .collect(toMap(m -> (String) m.get("Month"), 
       //the value is the map itself 
           m -> m, 
       //merging maps (i.e. adding the "Sales" and "NoOfTranx" infos) 
           (m1, m2) -> {m1.putAll(m2); return m1; })); 

//finally put that in a list 
List<Map<String, Object>> merge = new ArrayList<>(result.values()); 

Uwagi:

  • oryginalne mapy są modyfikowane - jeśli jest to niepożądane, możesz utworzyć new HashMap<>() w części scalającej.
  • dla lewego/prawego zewnętrznego sprzężenia, możesz przesyłać strumieniowo tylko jedną listę i dodawać odpowiednie wpisy w strumieniu
  • dla wewnętrznego łączenia możesz zacząć od jednej z listy, filtrować elementy znajdujące się na drugiej liście i kontynuować jak wyżej

Pełny przykład poniżej której drukuje:

list1 = [{Month=August-13, Sales=282200}, {Month=July-13, Sales=310400}] 
list2 = [{Month=August-13, NoOfTranx=6700}, {Month=July-13, NoOfTranx=14400}] 
merge = [{Month=August-13, Sales=282200, NoOfTranx=6700}, {Month=July-13, Sales=310400, NoOfTranx=14400}] 

Kod:

public static void main(String[] args) { 
    List<Map<String, Object>> list1 = new ArrayList<>(); 
    list1.add(map("Month", "August-13", "Sales", 282200)); 
    list1.add(map("Month", "July-13", "Sales", 310400)); 
    System.out.println("list1 = " + list1); 

    List<Map<String, Object>> list2 = new ArrayList<>(); 
    list2.add(map("Month", "August-13", "NoOfTranx", 6700)); 
    list2.add(map("Month", "July-13", "NoOfTranx", 14400)); 
    System.out.println("list2 = " + list2); 

    Map<String, Map<String, Object>> result = Stream.concat(list1.stream(), 
                  list2.stream()) 
       .collect(toMap(m -> (String) m.get("Month"), 
           m -> m, 
           (m1, m2) -> {m1.putAll(m2); return m1; })); 

    List<Map<String, Object>> merge = new ArrayList<>(result.values()); 
    System.out.println("merge = " + merge); 
} 

private static Map<String, Object> map(Object... kvs) { 
    Map<String, Object> map = new HashMap<>(); 
    for (int i = 0; i < kvs.length; i += 2) { 
     map.put((String) kvs[i], kvs[i+1]); 
    } 
    return map; 
} 
+0

gdzie Czy zdefiniowano toMap? –

+0

'import statyczny java.util.stream.Collectors.toMap;' – assylias

+0

Oto tylko jedna kolumna "Miesiąc", do którego dołączam. Co jeśli jest więcej niż jedna kolumna dla ex. {Month = August-13, Product = p1, Sales = 282200} i chcę dołączyć do produktu Month i Product? –

Powiązane problemy