Can you group List<TypeEnum> types = new ArrayList(Arrays.asList(TypeEnum.A, TypeEnum.B, TypeEnum.A));
into a Map<TypeEnum, Integer> countPerType;
, using functors (e.g. Google's Guava, Apache's Commons Functor) pre Java 8?
I'm trying to get my head around functional programming, but am unsure if that sort of thing would actually be possible (as I'm not just mapping a collections value, but trying to aggregate)?
In imperative style, I would have done something like this:
public Map<TypeEnum, Integer> countByGroup(List<TypeEnum> types) {
Map<TypeEnum, Integer> countedTypes = new HashMap<>();
for(TypeEnum type : types) {
if(countedTypes.containsKey(type)) {
countedTypes.put(type, countedTypes.get(type) + 1);
} else {
countedTypes.put(type, 1);
}
}
return countedTypes;
}
Procedure<TypeEnum> count = new Procedure<TypeEnum>() {
public Map<TypeEnum, Integer> countPerType = null;
@Override
public void run(TypeEnum type) {
if(countPerType.containsKey(type)) {
countPerType.put(type, countPerType.get(type) + 1);
} else {
countPerType.put(type, 1);
}
}
public Procedure<TypeEnum> init(Map<TypeEnum, Integer> countPerType) {
this.countPerType = countPerType;
return this;
}
}.init(countPerType); // kudos http://stackoverflow.com/a/12206542/2018047
Olivier Grégoire commented the correct answer:
Using Guava, you want a simple
Multiset
, and more specifically itsEnumMultiset
implementation.Multiset
is a data structure made to keep track of counted elements.
Given your List<TypeEnum> types
you can create an EnumMultiset
using create
:
Multiset<TypeEnum> multiset = EnumMultiset.create(types);
And you can query for the count of an element in the Multiset
using count
:
multiset.count(TypeEnum.A); // 2
multiset.count(TypeEnum.B); // 1