次の地図のリストがあります
List<Map<String, Object>> listBeforeGroup = new ArrayList<Map<String, Object>>();
Map<String, Object> m1 = new HashMap<String, Object>();
m1.put("company", "LG");
m1.put("billType", "A");
m1.put("billPeriod", "09-2018");
Map<String, Object> m2 = new HashMap<String, Object>();
m2.put("company", "LG");
m2.put("billType", "A");
m2.put("billPeriod", "09-2018");
Map<String, Object> m3 = new HashMap<String, Object>();
m3.put("company", "LG");
m3.put("billType", "A");
m3.put("billPeriod", "09-2018");
Map<String, Object> m4 = new HashMap<String, Object>();
m4.put("company", "LG");
m4.put("billType", "B");
m4.put("billPeriod", "01-2019");
Map<String, Object> m5 = new HashMap<String, Object>();
m5.put("company", "LG");
m5.put("billType", "B");
m5.put("billPeriod", "01-2019");
Map<String, Object> m6 = new HashMap<String, Object>();
m6.put("company", "Samsung");
m6.put("billType", "A");
m6.put("billPeriod", "10-2018");
Map<String, Object> m7 = new HashMap<String, Object>();
m7.put("company", "Samsung");
m7.put("billType", "A");
m7.put("billPeriod", "10-2018");
Map<String, Object> m8 = new HashMap<String, Object>();
m8.put("company", "Samsung");
m8.put("billType", "B");
m8.put("billPeriod", "11-2018");
listBeforeGroup.add(m1);listBeforeGroup.add(m2);
listBeforeGroup.add(m3);listBeforeGroup.add(m4);
listBeforeGroup.add(m5);listBeforeGroup.add(m6);
この出力を取得するにはどうすればよいですか?
//Desired Output - List<Map<String, Object>>
//{company=LG, billType=A, billPeriod=09-2018, count=3}
//{company=LG, billType=B, billPeriod=01-2019, count=2}
//{company=Samsung, billType=A, billPeriod=10-2018, count=2}
//{company=Samsung, billType=B, billPeriod=11-2018, count=1}
Java 8ストリームを使用してこれを試しましたが、目的の出力を取得できません
List<Map<String, Object>> listAfterGroup = listBeforeGroup.stream().map(m -> m.entrySet().stream().collect(Collectors.toMap(p -> p.getKey(), p - > p.getValue()))).collect(Collectors.toList());
これを試したところ、この解決策はマップを提供しますが、私はこれを望んでいません
Map<Object, Long> listAfterGroup = listBeforeGroup.stream().flatMap(m -> m.entrySet().stream()).collect(Collectors.groupingBy(Map.Entry::getKey,Collectors.counting()));
たとえば、「billPeriod」というキーでマップをグループ化し、値でアイテムをカウントして、マップの新しいリストを生成します。
Java 8での私のアプローチ:
Function<Map<String, Object>, String> createHashKey = map ->
map.values().stream()
.map(val -> String.valueOf(val))
.collect(Collectors.joining());
BinaryOperator<Map<String, Object>> mergeDuplicate = (map1, map2) -> {
int incrementedCount = (int)map1.get("count") + 1;
map1.put("count", incrementedCount);
return map1;
};
List<Map<String, Object>> listAfterGroup = listBeforeGroup.stream()
.collect(Collectors.toMap(createHashKey, el -> {
el.put("count", 1);
return el;
},mergeDuplicate))
.values().stream()
.collect(toList());
多分、最も簡潔な解決策ではないかもしれませんが、コードのロジックを理解するのは非常に読みやすく、簡単に理解できると思います。