问题
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;
}
EDIT: Relying on side effects seems somewhat inappropriate - or is that how it's done...?
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
回答1:
Olivier Grégoire commented the correct answer:
Using Guava, you want a simple Multiset, and more specifically its EnumMultiset 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
来源:https://stackoverflow.com/questions/41514257/can-you-use-a-functor-functional-programming-to-group-a-list-in-java-7-and-coun