import java.util.*;
import java.text.*;
import java.util.stream.*;
import java.util.function.*;
public class Test{
public static void main(String[] args){
Map hash1 = new HashMap();
hash1.put("CN", 5.3);
hash1.put("EU", 50);
hash1.put("US", 30);
Map hash2 = new HashMap();
hash2.put("CN", 6.5);
hash2.put("EU", 51.2);
hash2.put("DE", 35);
Map hash3 = new HashMap();
hash3.put("EU", 12.2);
hash3.put("DE", 311);
List> list = new ArrayList>();
list.add(hash1);
list.add(hash2);
list.add(hash3);
sop("input1 :");
sop(list);
sop("mergeKeyNumberValue output: ");
sop(mergeKeyNumberValue(list, Double.class));
Map a = new HashMap();
a.put("id", 1);
a.put("name", "name1");
a.put("val", 3);
//a.put("cnt", 30);
Map b = new HashMap();
b.put("id", 2);
b.put("name", "name2");
b.put("val", 4);
b.put("cnt", 40);
Map c = new HashMap();
c.put("id", 3);
c.put("name", "name3");
c.put("val", 5);
c.put("cnt", 50);
List> list1 = new ArrayList>();
list1.add(a);
list1.add(b);
list1.add(c);
Map a2 = new HashMap();
a2.put("id", 1);
a2.put("name", "name21");
a2.put("val", 7);
a2.put("cnt", 70);
Map b2 = new HashMap();
b2.put("id", 2);
b2.put("name", "name22");
b2.put("val", 8);
//b2.put("cnt", 80);
Map d2 = new HashMap();
d2.put("id", 4);
d2.put("name", "name24");
d2.put("val", 9);
d2.put("cnt", 90);
List> list2 = new ArrayList>();
list2.add(a2);
list2.add(b2);
list2.add(d2);
Map a3 = new HashMap();
a3.put("id", 1);
a3.put("name", "name21");
a3.put("val", 8);
a3.put("cnt", 33);
Map b3 = new HashMap();
b3.put("id", 2);
b3.put("name", "name22");
b3.put("val", 66);
//b3.put("cnt", 80);
Map e3 = new HashMap();
e3.put("id", 7);
e3.put("name", "name24");
e3.put("val", 8);
e3.put("cnt", 75);
List> list3 = new ArrayList>();
list3.add(a3);
list3.add(b3);
list3.add(e3);
String idField = "id";
String[] addValues = new String[]{"val", "cnt"};
List>> ll = new ArrayList>>();
ll.add(list1);
ll.add(list2);
ll.add(list3);
sop("input: ");
sop(ll);
sop("mergeListMap output: ");
sop(mergeListMap(ll, idField, addValues, Integer.class));
}
/*
* param: [{EU=50, CN=5.3, US=30}, {EU=51.2, DE=35, CN=6.5}, {EU=12.2, DE=311}]
* param: Double.class
* return: {EU=113.4, DE=346.0, CN=11.8, US=30}
*/
private static Map mergeKeyNumberValue(List> list, Class extends Number> clazz){
BinaryOperator mergeFunction = null;
mergeFunction = (v1, v2) -> addTwoNumberValue(v1, v2, clazz);
Map ret = list.stream()
.map(Map::entrySet)
.flatMap(Set::stream)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, mergeFunction));
return ret;
}
/*
* param: [[{val=3, name=name1, id=1}, {val=4, name=name2, cnt=40, id=2}, {val=5, name=name3, cnt=50, id=3}], [{val=7, name=name21, cnt=70, id=1}, {val=8, name=name22, id=2}, {val=9, name=name24, cnt=90, id=4}], [{val=8, name=name21, cnt=33, id=1}, {val=66, name=name22, id=2}, {val=8, name=name24, cnt=75, id=7}]]
* param: "id"
* param: ["val","cnt"]
* param: Integer.class
* return: [{cnt=103, val=18, name=name1, id=1}, {val=78, name=name2, cnt=40, id=2}, {val=5, name=name3, cnt=50, id=3}, {val=9, name=name24, cnt=90, id=4}, {val=8, name=name24, cnt=75, id=7}]
*/
private static List> mergeListMap(List>> list, String idField, String[] addFields, Class extends Number> clazz){
List>> lm = new ArrayList>>();
for(List> tl : list){
lm.add(tl.stream().collect(Collectors.toMap(m1 -> m1.get(idField), v -> v, (v1, v2) -> v1)));
}
final BinaryOperator mergeFunction = (v1, v2) -> addTwoNumberValue(v1, v2, clazz);
Map> ret = lm.stream()
.map(Map::entrySet)
.flatMap(Set::stream)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
(v1t, v2t) -> {
Map v3 = new HashMap((Map) v1t);
for(String addField : addFields){
try{
v3.merge(addField, ((Map) v2t).get(addField), mergeFunction);
}catch(Exception e){}
}
return v3;
}));
List> retList = new ArrayList>(ret.values());
return retList;
}
private static T getNumberValue(Object obj, Class clazz){
if(obj==null)return null;
if (clazz == Integer.class) {
return clazz.cast(Integer.parseInt(String.valueOf(obj)));
} else if (clazz == Double.class) {
return clazz.cast(Double.parseDouble(String.valueOf(obj)));
} else if (clazz == Float.class) {
return clazz.cast(Float.parseFloat(String.valueOf(obj)));
} else if (clazz == Long.class) {
return clazz.cast(Long.parseLong(String.valueOf(obj)));
}
return null;
}
private static T addTwoNumberValue(Object obj1, Object obj2, Class clazz){
if(obj1==null)return null;
if (clazz == Integer.class) {
return clazz.cast(Integer.parseInt(String.valueOf(obj1)) + Integer.parseInt(String.valueOf(obj2)));
} else if (clazz == Double.class) {
return clazz.cast(Double.parseDouble(String.valueOf(obj1)) + Double.parseDouble(String.valueOf(obj2)));
} else if (clazz == Float.class) {
return clazz.cast(Float.parseFloat(String.valueOf(obj1)) + Float.parseFloat(String.valueOf(obj2)));
} else if (clazz == Long.class) {
return clazz.cast(Long.parseLong(String.valueOf(obj1)) + Long.parseLong(String.valueOf(obj2)));
}
return null;
}
public static void sop(Object obj){
System.out.println(obj.toString());
}
}