Reputation: 149
I need to count occurences of some special bundles.
Map<Integer,Integer> countBundles(){
return bundles.stream()
.bla()
.bla()
.bla()
.collect(groupingBy(Bundle::getId), counting()));
}
This code does not compile because counting returns Long. Is there any beautiful way to return Map<Integer, Integer>?
I have this idea, but it`s ugly
map.entrySet().stream()
.collect(toMap(Map.Entry::getKey, entry -> (int) entry.getValue().longValue()));
Upvotes: 3
Views: 3392
Reputation: 12932
You can use Collectors.collectingAndThen
to apply a function to the result of your Collector:
Map<Integer,Integer> countBundles() {
return bundles.stream()
.bla()
.bla()
.bla()
.collect(groupingBy(Bundle::getId, collectingAndThen(counting(), Long::intValue)));
}
If you need some other semantics than just a cast, replace Long::intValue
with some other conversion code.
Upvotes: 10
Reputation: 2863
There is no build-in way to use Collectors.counting()
with Integer
, since generics are invariant. However, you can write a custom Collector
with minimal effort:
public static <T> Collector<T, ?, Integer> countingInt() {
return Collectors.summingInt(e -> 1);
}
You can also use the plain summingInt(e -> 1)
if you want to use native libraries only.
Example:
Map<Integer,Integer> countBundles(){
return bundles.stream()
.bla()
.bla()
.bla()
// 1 .collect(groupingBy(Bundle::getId), countingInt()));
// 2 .collect(groupingBy(Bundle::getId), summingInt(e -> 1)));
}
Please note that with signed interpretation, you can count at most 2.147.483.647
elements.
Upvotes: 5