java 使用 HashMap 统计实例数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13163547/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 11:42:55  来源:igfitidea点击:

Using HashMap to count instances

javahashmapequalshashcode

提问by lynks

I have the following code to count the instances of different strings in an array;

我有以下代码来计算数组中不同字符串的实例;

String words[] = {"the","cat","in","the","hat"};
HashMap<String,Integer> wordCounts = new HashMap<String,Integer>(50,10);
for(String w : words) {
    Integer i = wordCounts.get(w);
    if(i == null) wordCounts.put(w, 1);
    else wordCounts.put(w, i + 1);
}

Is this a correct way of doing it? It seems a bit long-winded for a simple task. The HashMapresult is useful to me because I will be indexing it by the string.

这是正确的做法吗?对于一个简单的任务来说,这似乎有点冗长。的HashMap,因为我会被串编入索引的结果对我有用。

I am worried that the line

我担心线路

else wordCounts.put(w, i + 1);

could be inserting a second key-valuepair due to the fact that

可能会插入第二key-value对,因为

new Integer(i).equals(new Integer(i + 1));

would be false, so two Integerswould end up under the same Stringkey bucket, right? Or have I just over-thought myself into a corner?

会是假的,所以两个Integers最终会在同一个String关键桶下,对吧?还是我只是把自己想得太多了?

回答by Jon Skeet

Your code will work- but it would be simpler to use HashMultisetfrom Guava.

您的代码将工作-但它是易于使用HashMultiset番石榴

// Note: prefer the below over "String words[]"
String[] words = {"the","cat","in","the","hat"};
Multiset<String> set = HashMultiset.create(Arrays.asList(words));

// Write out the counts...
for (Multiset.Entry<String> entry : set.entrySet()) {
    System.out.println(entry.getElement() + ": " + entry.getCount());
}

回答by Amit Deshpande

Yes you are doing it correct way. HashMap replaces values if same key is provided.

是的,您正在以正确的方式进行操作。如果提供相同的键,HashMap 将替换值。

From Java doc of HashMap#put

来自 Java 文档 HashMap#put

Associates the specified value with the specified key in this map. If the map previously contained a mapping for the key, the old value is replaced.

将指定值与此映射中的指定键相关联。如果映射先前包含键的映射,则旧值将被替换。

回答by Petar Minchev

Your code is perfectly fine. You map strings to integers. Nothing is duplicated.

你的代码非常好。您将字符串映射到整数。没有什么是重复的。

回答by kosa

HashMap don't allow duplicate keys, so there is no way to have more than one SAME key-value pairs in your map.

HashMap 不允许重复的,因此您的映射中不可能有多个相同的键值对。

回答by Priot

Here is a String-specific counter that should be genericized and have a sort by value option for toString(), but is an object-oriented wrapper to the problem, since I can't find anything similar:

这是一个特定于字符串的计数器,它应该被泛化并为 toString() 提供一个按值排序的选项,但它是一个面向对象的问题包装器,因为我找不到任何类似的东西:

package com.phogit.util;

import java.util.Map;
import java.util.HashMap;

import java.lang.StringBuilder;

public class HashCount {

    private final Map<String, Integer> map = new HashMap<>();

    public void add(String s) {
        if (s == null) {
            return;
        }
        Integer i = map.get(s);
        if (i == null) {
            map.put(s, 1);
        } else {
            map.put(s, i+1);
        }
    }

    public int getCount(String s) {
        if (s == null) {
            return -1;
        }
        Integer i = map.get(s);
        if (i == null) {
            return -1;
        }
        return i;
    }

    public String toString() {
        if (map.size() == 0) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        // sort by key for now
        Map<String, Integer> m = new TreeMap<String, Integer>(map);
        for (Map.Entry pair : m.entrySet()) {
            sb.append("\t")
              .append(pair.getKey())
              .append(": ")
              .append(pair.getValue())
              .append("\n");;
        }
        return sb.toString();
    }

    public void clear() {
        map.clear();
    }
}

回答by Marc Schmid

Your code looks fine to me and there is no issue with it. Thanks to Java 8 features it can be simplified to:

你的代码对我来说看起来不错,它没有问题。由于 Java 8 的特性,它可以简化为:

String words[] = {"the","cat","in","the","hat"};
HashMap<String,Integer> wordCounts = new HashMap<String,Integer>(50,10);
for(String w : words) {
     wordCounts.merge(w, 1, (a, b) -> a + b);
}

the follwowing code

以下代码

System.out.println("HASH MAP DUMP: " + wordCounts.toString());

would print out.

会打印出来。

HASH MAP DUMP: {cat=1, hat=1, in=1, the=2}