是否存在Python 3的集合的scala/java等价物.Counter

Sal*_*ley 8 python java scala

我想要一个可以计算我拥有的对象数量的类 - 听起来收集所有对象然后对它们进行分组会更有效.

Python在collections.Counter中有一个理想的结构,Java或Scala有类似的类型吗?

Bor*_*der 13

从您链接的文档:

Counter类与其他语言的bag或multisets类似.

Java没有Multiset类或类似物.番石榴有一个MultiSet集合,完全符合你的要求.

在纯Java中,您可以使用a Map<T, Integer>和新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));
Run Code Online (Sandbox Code Playgroud)

输出:

2
3
0
Run Code Online (Sandbox Code Playgroud)

您可以class在几行代码中包含此行为:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

使用这样:

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"));
Run Code Online (Sandbox Code Playgroud)

输出:

2
3
0
Run Code Online (Sandbox Code Playgroud)


Dav*_*ave 10

不是我所知道的.但scala非常富有表现力,允许你自己做类似的东西:

def counts[T](s: Seq[T]) = s.groupBy(x => x).mapValues(_.length)
Run Code Online (Sandbox Code Playgroud)

编辑:更简洁:

def counts[T](s: Seq[T]) = s.groupBy(identity).mapValues(_.length)
Run Code Online (Sandbox Code Playgroud)


The*_*aul 5

另一个scala版本,一次性完成,避免 .groupBy

val l = List("a", "b", "b", "c", "b", "c", "b", "d")

l.foldLeft(Map[String, Int]() withDefaultValue (0))
          { (m, el) => m updated (el, m(el)+1)}
//> res1: Map(a -> 1, b -> 4, c -> 2, d -> 1)
Run Code Online (Sandbox Code Playgroud)

或者如果您不想使用默认值为零的地图

l.foldLeft(Map[String, Int]()) { (m, el) => m updated (el, m.getOrElse(el,0)+1)}
Run Code Online (Sandbox Code Playgroud)