您可以使用Java 8之前的函子(例如Google's GuavaApache's Commons Functor)将List<TypeEnum> types = new ArrayList(Arrays.asList(TypeEnum.A, TypeEnum.B, TypeEnum.A));分组为Map<TypeEnum, Integer> countPerType;吗?

我正在尝试着手进行函数式编程,但是不确定这种事情是否真的可能实现(因为我不仅在映射集合值,而且试图进行汇总)?

以命令式风格,我会做这样的事情:

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正确答案:


  使用Guava,您需要一个简单的Multiset,更具体地说是它的EnumMultiset实现。 Multiset是用于跟踪计数元素的数据结构。


给定您的List<TypeEnum> types,您可以使用EnumMultiset创建一个create

Multiset<TypeEnum> multiset = EnumMultiset.create(types);


您可以使用Multisetcount中查询元素的计数:

multiset.count(TypeEnum.A); // 2
multiset.count(TypeEnum.B); // 1

08-04 21:29