计算java集合中出现次数的优雅方法

fo_*_*x86 30 java collections

给定一组可能重复的对象,我想最终得到每个对象的出现次数.我通过初始化一个空来做Map,然后迭代Collection并将对象映射到它的计数(每次地图已经包含对象时递增计数).

 public Map<Object, Integer> countOccurrences(Collection<Object> list){
      Map<Object, Integer> occurrenceMap = new HashMap<Object, Integer>();

      for(Object obj: list){
           Integer numOccurrence = occurrenceMap.get(obj);
           if(numOccurrence == null){
                //first count
                occurrenceMap.put(obj, 1);
           } else{
                occurrenceMap.put(obj, numOccurrence++);
           }
      }
      return occurrenceMap;
 }
Run Code Online (Sandbox Code Playgroud)

对于计算出现次数的简单逻辑,这看起来过于冗长.有更优雅/更短的方式吗?我对一个完全不同的算法或java语言特定功能开放,允许更短的代码.

Tom*_*yre 20

查看Guava的Multiset.几乎就是你要找的东西.

不幸的是它没有addAll(Iterable iterable)函数,但是在你的集合中调用add(E e)的简单循环很容易.

编辑

我的错误,它确实有一个addAll方法 - 因为它必须,因为它实现了Collection.


xin*_*123 20

现在让我们尝试一些Java 8代码:

static public Map<String,Integer> toMap(List<String> lst){

    return lst.stream()
        .collect(HashMap<String,Integer>::new,
                 (map,str) ->{
                     if(!map.containsKey(str)){
                         map.put(str,1);
                     }else{
                         map.put(str,map.get(str)+1);
                     }
                 },
                 HashMap<String,Integer>::putAll);
}
static public Map<String,Integer> toMap(List<String> lst){
    return lst.stream().collect(Collectors.groupingBy(s -> s, 
                                  Collectors.counting()));
}
Run Code Online (Sandbox Code Playgroud)

我觉得这段代码比较优雅

  • 使用这样的累加器更加优雅:`(map,str) - > map.merge(str,1,(old,one) - > old + one)` (2认同)

Mat*_*uiz 10

我知道这是一个老问题,但我在Java 8中找到了一种更优雅的方式来计算这些投票,希望你喜欢它.

Map<String, Long> map = a.getSomeStringList()
            .stream()
            .collect(Collectors.groupingBy(
                    Function.identity(),
                    Collectors.counting())
            );
Run Code Online (Sandbox Code Playgroud)

任何错误,只是评论.


Vic*_*Vic 6

查看本文如何计算List中元素的出现次数.对于计数出现,您可以使用int occurrences = Collections.frequency(list, obj);.

  • `Collections.frequency`可以计算一些特定的对象.但是OP需要的是计算所有对象的频率,这使得该方法非常低效. (5认同)