Using HashMap to count instances

為{幸葍}努か 提交于 2019-12-22 07:52:27

问题


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 HashMap result is useful to me because I will be indexing it by the string.

I am worried that the line

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

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

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

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


回答1:


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

From Java doc of 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.




回答2:


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

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



回答3:


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




回答4:


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




回答5:


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:

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



回答6:


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

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}


来源:https://stackoverflow.com/questions/13163547/using-hashmap-to-count-instances

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!