我有一个数组列表,一个Java的集合类,如下所示:

ArrayList<String> animals = new ArrayList<String>();
animals.add("bat");
animals.add("owl");
animals.add("bat");
animals.add("bat");

如您所见,animals数组列表由3个bat元素和1个owl元素组成。我想知道在Collection框架中是否有返回蝙蝠出现次数的API,或者是否有另一种方法来确定出现次数。

我发现谷歌的集合Multiset确实有一个API,返回一个元素的总出现次数。但是这只与JDK 1.5兼容。我们的产品目前是JDK 1.6,所以我不能使用它。


当前回答

实际上,Collections类有一个名为:frequency(Collection c, Object o)的静态方法,它返回你正在搜索的元素的出现次数,顺便说一下,这将为你完美地工作:

ArrayList<String> animals = new ArrayList<String>();
animals.add("bat");
animals.add("owl");
animals.add("bat");
animals.add("bat");
System.out.println("Freq of bat: "+Collections.frequency(animals, "bat"));

其他回答

一个稍微有效一点的方法可能是

Map<String, AtomicInteger> instances = new HashMap<String, AtomicInteger>();

void add(String name) {
     AtomicInteger value = instances.get(name);
     if (value == null) 
        instances.put(name, new AtomicInteger(1));
     else
        value.incrementAndGet();
}

你可以在你的用例中使用Java 8的groupingBy特性。

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

public class Test {
    public static void main(String[] args) {
        List<String> animals = new ArrayList<>();

        animals.add("bat");
        animals.add("owl");
        animals.add("bat");
        animals.add("bat");

        Map<String,Long> occurrenceMap =
                animals.stream().collect(Collectors.groupingBy(Function.identity(),Collectors.counting()));
        System.out.println("occurrenceMap:: " + occurrenceMap);
    }
}

输出

occurrenceMap:: {bat=3, owl=1}

抱歉,没有简单的方法调用可以做到这一点。你所需要做的就是创建一个地图并计算频率。

HashMap<String,int> frequencymap = new HashMap<String,int>();
foreach(String a in animals) {
  if(frequencymap.containsKey(a)) {
    frequencymap.put(a, frequencymap.get(a)+1);
  }
  else{ frequencymap.put(a, 1); }
}

Java 8 -另一种方法

String searched = "bat";
long n = IntStream.range(0, animals.size())
            .filter(i -> searched.equals(animals.get(i)))
            .count();

我想知道,为什么你不能在JDK 1.6中使用谷歌的Collection API。上面这么说吗?我认为可以,不应该有任何兼容性问题,因为它是为较低版本构建的。如果它是为1.6构建的,而你运行的是1.5,情况就会有所不同。

我哪里说错了吗?