Java的Python计数器替代方案

Java的Python计数器替代方案,java,python,sorting,data-structures,Java,Python,Sorting,Data Structures,我一直在使用Python中的Counter()数据结构作为键值存储,它允许我使用最常用的方法根据对象的值对对象进行排序。更多信息 Java语言是否有类似的数据结构?例如,我看到了许多相关的答案,这些答案侧重于排序或按数据结构进行排序,但最初并不是为此目的定义的。在我的例子中,我通常需要保留对象的计数器,然后选择最常见的或得分最高的(Top-N查询)。但是,这对我来说很困难,因为我需要插入到HashMap,然后进行排序或使用多个数据结构。来自: 计数器类类似于其他语言中的bags或Multiset

我一直在使用Python中的Counter()数据结构作为键值存储,它允许我使用最常用的方法根据对象的值对对象进行排序。更多信息

Java语言是否有类似的数据结构?例如,我看到了许多相关的答案,这些答案侧重于排序或按数据结构进行排序,但最初并不是为此目的定义的。在我的例子中,我通常需要保留对象的计数器,然后选择最常见的或得分最高的(Top-N查询)。但是,这对我来说很困难,因为我需要插入到HashMap,然后进行排序或使用多个数据结构。

来自:

计数器类类似于其他语言中的bags或Multiset

Java没有多集类或类似类。番石榴有一个多集收集,这正是你想要的

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中,您可以使用映射和新的合并方法:

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));
您可以用几行代码将此行为包装到类中:

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);
    }
}

下面是一个类,它似乎实现了足够多的
计数器
,可以执行您想要的操作

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));
}
静态类计数器{
最终ConcurrentMap计数=新ConcurrentHashMap();
公开作废认沽权(T it){
加(it,1);
}
公共无效添加(T it,int v){
merge(it,v,Integer::sum);
}
公共列表最常见(int n){
返回计数。entrySet().stream()
//按值排序。
.sorted((e1,e2)->Integer.compare(e2.getValue(),e1.getValue())
//顶。
.限制(n)
//只有钥匙。
.map(e->e.getKey())
//作为一个列表。
.collect(Collectors.toList());
}
}
公开无效测试(){
计数器c=新计数器();
字符串[]数字={“零”、“一”、“二”、“三”、“四”、“五”、“六”};
for(int i=0;i

它使用Java 8功能。

也许您想要的是问题的答案。我登录只是为了对此进行投票-谢谢。我还注意到,
mostCommon
方法实际上返回最不常用的元素。编辑被拒绝了,我不太清楚为什么。但我至少想给使用这个-switch
Integer.compare(e1.getValue(),e2.getValue())
Integer.compare(e2.getValue(),e1.getValue())
的人留个便条,以便得到最常见的elements@MylesHollowed-接得好-谢谢提醒-修正了。
2
3
0
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));
}