您可以使用 functor/functional 编程对 Java 7 中的列表进行分组(并计算每组的元素数)吗?

Can you use a functor/functional programming to group a list in Java 7 (and count its elements per group)?

你能否使用仿函数(例如 Google's Guava, Apache's Commons Functor)将 List<TypeEnum> types = new ArrayList(Arrays.asList(TypeEnum.A, TypeEnum.B, TypeEnum.A)); 分组为 Map<TypeEnum, Integer> countPerType; pre Java 8?

我正在尝试了解函数式编程,但我不确定这种事情是否真的可行(因为我不只是映射集合值,而是尝试聚合)?

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

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 

Olivier Grégoire 正确答案:

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.

鉴于你的 List<TypeEnum> types 你可以使用 create 创建一个 EnumMultiset:

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

并且您可以使用 count:

查询 Multiset 中元素的计数
multiset.count(TypeEnum.A); // 2
multiset.count(TypeEnum.B); // 1