Java 使用HashMap计算实例数

Java 使用HashMap计算实例数,java,hashmap,equals,hashcode,Java,Hashmap,Equals,Hashcode,我有以下代码来计算数组中不同字符串的实例 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,

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

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);
}
可能正在插入第二个
键值
对,因为

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

将为false,因此两个
整数将在相同的
字符串下结束,对吗?还是我只是过度地认为自己陷入了困境?

是的,你的做法是正确的。如果提供相同的键,HashMap将替换值

来自

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


你的代码非常好。将字符串映射为整数。没有重复的项。

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

您的代码可以工作-但是从中使用
HashMultiset
会更简单

//注意:与“字符串[]”相比,更喜欢下面的内容
String[]words={“the”、“cat”、“in”、“the”、“hat”};
Multiset set=HashMultiset.create(Arrays.asList(words));
//把计数写出来。。。
for(Multiset.Entry:set.entrySet()){
System.out.println(entry.getElement()+“:“+entry.getCount());
}

这是一个特定于字符串的计数器,它应该被泛化,并为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();
    }
}
package com.phogit.util;
导入java.util.Map;
导入java.util.HashMap;
导入java.lang.StringBuilder;
公共类哈希计数{
私有最终映射=新HashMap();
公共无效添加(字符串s){
如果(s==null){
返回;
}
整数i=map.get(s);
如果(i==null){
地图.put(s,1);;
}否则{
地图放置(s,i+1);
}
}
public int getCount(字符串s){
如果(s==null){
返回-1;
}
整数i=map.get(s);
如果(i==null){
返回-1;
}
返回i;
}
公共字符串toString(){
if(map.size()==0){
返回null;
}
StringBuilder sb=新的StringBuilder();
//现在按键排序
Map m=新树形图(Map);
对于(Map.Entry对:m.entrySet()){
某人附加(“\t”)
.append(pair.getKey())
.附加(“:”)
.append(pair.getValue())
.append(“\n”);;
}
使某人返回字符串();
}
公共空间清除(){
map.clear();
}
}

我觉得你的代码很好,没有问题。由于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);
}
我会打印出来

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

我觉得很好;我会这样做的。试试看;)@Vulcan我正要这么做,但我认为我的整个方法可能很糟糕,所以我想我应该把它放在这里。好的代码应该使用
Map
接口。谢谢,主要的失败时刻。我整个星期都在与各种
系列
合作。当然,
values.equals()
是不相关的,都是关于键的!谢谢,乔恩,我会调查的。那太好了,谢谢。关于数组语法:我觉得站在那一个旁边我正在打一场失败的战斗:P@lynks:您究竟为什么要将类型信息分成两部分?变量的类型是“字符串数组”——如果这是一个旧的C或C++习惯,那么就扔掉那些在新语言中没有意义的规矩是值得的。我完全理解,事实上,我知道我错了。我想我只是不喜欢在索引数组时在一个地方看到[],然后在另一个地方看到[]。是的,这是一个古老的C习惯。@lynks:他们在做非常不同的事情——一个是索引到数组中,另一个是说你感兴趣的类型是数组。就我个人而言,我真的不喜欢Java甚至允许“拆分”语法的事实。Euch。OP写了一段代码,用4行代码做同样的事情,为什么要这么做呢?根据我的经验,使用对象可以更容易地编程。还演示了在查看结果时如何按键顺序迭代。
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);
}
System.out.println("HASH MAP DUMP: " + wordCounts.toString());
HASH MAP DUMP: {cat=1, hat=1, in=1, the=2}