我有Stream<Map<String, String>>
,其中每个地图就像一个单独的记录,并且包含两个条目:
此列表可能包含重复的地图,其方式是2张或多张地图可能具有相同的car ID输入值。 基本上是这样的:entry1.get(“ ID”)== entry2.get(“ ID”)。我想做的是删除具有重复ID的地图,然后将KMI值合并在一起。 这个:
{“ ID”:“ 1003”,“ KMI”:“ 500”},{“ ID”:“ 1003”,“ KMI”:“ 400”}, {“ ID”:“ 1004”,“ KMI”:“ 200”}
应该变成这样:
{“ ID”:“ 1003”,“ KMI”:“ 900”},{“ ID”:“ 1004”,“ KMI”:“ 200”}
我曾尝试单独使用流API来执行此操作,但我对此一无所知。我试图修改一个具有对象列表的类似示例 这是到目前为止我得到的:
List<Map<String, String>> result = new ArrayList<>(
queryKmAll.collect(
Collectors.toMap(a1 -> a1.get("ID")), Function.identity(), (Map<String, String> m2, Map<String, String> m1) -> {
m1.put("KMI", String.valueOf(Double.parseDouble(m1.get("KMI")) + Double.parseDouble(m2.get("KMI"))));
return m1;
})
)
);
答案 0 :(得分:2)
我从OP离开的地方接了。我对您的逻辑做了一些修改,以返回您想要的内容。看看它。希望对您有帮助
Collectors.toMap将返回一个以ID
作为键,以sum of KMI
作为Function.identity()
情况的地图。因此,返回值为Map<Object,Map<String,String>>
。因为预期的输出为Stream<Map<String,String>
,所以我添加了.values().stream()
。
Stream<Map<String, String>> result = queryKmAll.collect(Collectors.toMap(a1 -> a1.get("ID"),
Function.identity(), (Map<String, String> m2, Map<String, String> m1) -> {
m1.put("KMI",
String.valueOf(Double.parseDouble(m1.get("KMI")) + Double.parseDouble(m2.get("KMI"))));
return m1;
})).values().stream();
result.forEach(System.out::println);
答案 1 :(得分:1)
您要寻找的是Collectors.groupingBy:
Map<String, Long> summary = Stream
.of(
new HashMap<String, String>() {{
put("ID", "1003");
put("KMI", "500");
}},
new HashMap<String, String>() {{
put("ID", "1003");
put("KMI", "400");
}},
new HashMap<String, String>() {{
put("ID", "1004");
put("KMI", "200");
}}
)
.collect(Collectors.groupingBy(
m -> m.get("ID"),
Collectors.summingLong(m -> Long.valueOf(m.get("KMI")))
));
System.out.println(summary);
此外,您可以将地图替换为一个类,例如Summary
:
public class Summary {
public Summary(String id, Long kmi) {
this.id = id;
this.kmi = kmi;
}
private String id;
private Long kmi;
public String getId() {
return id;
}
public Long getKmi() {
return kmi;
}
}
然后使用:
Map<String, Long> summary = Stream
.of(
new Summary("1003", 500L),
new Summary("1003", 400L),
new Summary("1004", 200L)
)
.collect(Collectors.groupingBy(
s -> s.getId(),
Collectors.summingLong(s -> s.getKmi())
));
System.out.println(summary);
打印:
{1004=200, 1003=900}
答案 2 :(得分:1)
您首先需要按ID分组,然后在每个组中添加KMI:
// stream is your initial stream
List<Map<String, String>> list = stream.collect(Collectors.groupingBy(x -> x.get("ID")))
.entrySet().stream().map(x -> {
List<Map<String, String>> value = x.getValue();
int kmSum = value.stream().mapToInt(y -> Integer.parseInt(y.get("KMI"))).sum();
HashMap<String, String> map = new HashMap<>();
map.put("ID", x.getKey());
map.put("KMI", Integer.toString(kmSum));
return map;
}).collect(Collectors.toList());