您可以使用函子/函数式编程在 Java 7 中对列表进行分组(并计算每组的元素)吗?
你可以分组List
到 Map
,使用函子(例如 Google 的 Guava,Apache 的 Commons Functor) pre Java 8?
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;
}
依赖副作用似乎有些不合适 - 或者它是如何完成的......?
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
Olivier Grégoire 评论正确答案:
使用 Guava,您需要一个简单的 Multiset
,更具体地说是它的 EnumMultiset
实现.Multiset
是一种用于跟踪计数元素的数据结构.
Using Guava, you want a simple
Multiset
, and more specifically itsEnumMultiset
implementation.Multiset
is a data structure made to keep track of counted elements.
给定你的 List
你可以使用 create
:
Given your List<TypeEnum> types
you can create an EnumMultiset
using create
:
Multiset<TypeEnum> multiset = EnumMultiset.create(types);
您可以使用 count
:
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