问题
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.
Multisetis 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