Let's say I have a List
of classes that each has a Map
.
public class Test {
public Map<Long, Integer> map;
}
the Long
keys in the Map
are timestamps and the Integer
values are scores.
I am trying to create a Stream
that can combine the maps from all objects and output a Map
with the unique Timestamps (The Long
s) and an average score.
I have this code, but it gives me the sum of all the scores and not the average (The Integer
class doesn't have an average method).
Test test1 = new Test();
test1.map = new HashMap() {{
put(1000L, 1);
put(2000L, 2);
put(3000L, 3);
}};
Test test2 = new Test();
test2.map = new HashMap() {{
put(1000L, 10);
put(2000L, 20);
put(3000L, 30);
}};
List<Test> tests = new ArrayList() {{
add(test1);
add(test2);
}};
Map<Long, Integer> merged = tests.stream()
.map(test -> test.map)
.map(Map::entrySet)
.flatMap(Collection::stream)
.collect(
Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
Integer::sum
)
);
System.out.println(merged);
I'm thinking that this might not be an easy problem so solve in a single Stream
, so an output with a Map
with the unique timestamps and a List
of all the scores would also be fine. Then I can calculate the average myself.
Map<Long, List<Integer>>
It it possible?
Instead of Collectors.toMap
use Collectors.groupingBy
:
Map<Long, Double> merged = tests.stream()
.map(test -> test.map)
.map(Map::entrySet)
.flatMap(Collection::stream)
.collect(
Collectors.groupingBy(
Map.Entry::getKey,
Collectors.averagingInt(Map.Entry::getValue)
)
);
Oh, and even though you probably don't need it anymore, you can get the Map<Long, List<Integer>>
you asked about in the last part of your question just as easily:
Map<Long, List<Integer>> merged = tests.stream()
.map(test -> test.map)
.map(Map::entrySet)
.flatMap(Collection::stream)
.collect(
Collectors.groupingBy(
Map.Entry::getKey,
Collectors.mapping(Map.Entry::getValue, Collectors.toList())
)
);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.