2017-01-06 43 views
1

你能組List<TypeEnum> types = new ArrayList(Arrays.asList(TypeEnum.A, TypeEnum.B, TypeEnum.A));Map<TypeEnum, Integer> countPerType;,使用仿函數(例如Google's GuavaApache's Commons Functor的Java 8?我試圖讓我的頭繞函數式編程,但我不確定這種事情實際上是可能的(因爲我不只是映射集合值,但試圖聚合)?您可以使用函子/函數式編程在Java 7中對列表進行分組(並對每個組的元素進行計數)?

在命令式的風格,我會做這樣的事情:

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 
+2

使用番石榴,你想要一個簡單的['Multiset'](http://google.github.io/guava/releases/20.0/api/docs/com/google/common/collect/Multiset.html),更具體地說它的['' EnumMultiset'](http://google.github.io/guava/releases/20.0/api/docs/com/google/common/collect/EnumMultiset.html)實現。 'Multiset'是一個數據結構,用於跟蹤計數的元素。 –

+0

Java 8並不具有魔力,即Stream API由使用接口類型參數的普通Java代碼組成。沒有理由不在Java8之前的環境中工作。 – Holger

+0

是的,我知道。正如我所說的,我試圖通過使用函數式編程以Java8ish風格的方式解決問題 - 但不能夠使用Java 8本身...... :) – Christian

回答

1

Olivier Grégoirecommented正確答案:

使用番石榴,你想要一個簡單的Multiset,更具體的實施EnumMultisetMultiset是用於跟蹤計數元素的數據結構。

鑑於你List<TypeEnum> types您可以使用create創建EnumMultiset

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

,並且可以使用countMultiset元素的統計查詢:

multiset.count(TypeEnum.A); // 2 
multiset.count(TypeEnum.B); // 1 
相關問題