来自这里:
Counter类类似于其他语言中的bags或multisets。
Java没有Multiset类或相似的类。Guava有一个MultiSet集合,可以完全满足你的需求。
在纯Java中,您可以使用Map和新的merge方法:
final Map<String, Integer> counts = new HashMap<>();
counts.merge("Test", 1, Integer::sum);
counts.merge("Test", 1, Integer::sum);
counts.merge("Other", 1, Integer::sum);
counts.merge("Other", 1, Integer::sum);
counts.merge("Other", 1, Integer::sum);
System.out.println(counts.getOrDefault("Test", 0));
System.out.println(counts.getOrDefault("Other", 0));
System.out.println(counts.getOrDefault("Another", 0));
输出:
2
3
0
public class Counter<T> {
final Map<T, Integer> counts = new HashMap<>();
public void add(T t) {
counts.merge(t, 1, Integer::sum);
}
public int count(T t) {
return counts.getOrDefault(t, 0);
}
}
并像这样使用它:
final Counter<String> counts = new Counter<>();
counts.add("Test");
counts.add("Test");
counts.add("Other");
counts.add("Other");
counts.add("Other");
System.out.println(counts.count("Test"));
System.out.println(counts.count("Other"));
System.out.println(counts.count("Another"));
输出:
2
3
0
Counter
类,可以满足你的需求。static class Counter<T> {
final ConcurrentMap<T, Integer> counts = new ConcurrentHashMap<>();
public void put(T it) {
add(it, 1);
}
public void add(T it, int v) {
counts.merge(it, v, Integer::sum);
}
public List<T> mostCommon(int n) {
return counts.entrySet().stream()
// Sort by value.
.sorted((e1, e2) -> Integer.compare(e2.getValue(), e1.getValue()))
// Top n.
.limit(n)
// Keys only.
.map(e -> e.getKey())
// As a list.
.collect(Collectors.toList());
}
}
public void test() {
Counter<String> c = new Counter<>();
String[] numbers = {"Zero", "One", "Two", "Three", "Four", "Five", "Six"};
for (int i = 0; i < numbers.length; i++) {
c.add(numbers[i], i);
}
System.out.println(c.mostCommon(3));
}
它使用Java 8的功能。
mostCommon
方法实际上返回的是最不常见的元素。这个修改被拒绝了,我也不太确定为什么。但我至少想给那些使用它的人留个备注 - 在比较时将Integer.compare(e1.getValue(), e2.getValue())
改为Integer.compare(e2.getValue(), e1.getValue())
以获取最常见的元素。 - Myles Hollowed