【问题标题】:Using HashMap to count instances使用HashMap统计实例
【发布时间】:2012-10-31 17:29:43
【问题描述】:

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

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

这是正确的做法吗?一个简单的任务似乎有点啰嗦。 HashMap 结果对我很有用,因为我将按字符串对其进行索引。

我担心线路

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

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

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

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

【问题讨论】:

  • 我觉得不错;我就是这样做的。试试看;)
  • @Vulcan 我正要这样做,但认为我的整个方法可能很糟糕,所以我想我会把它扔在这里。
  • 好的代码应该使用Map&lt;K, V&gt;接口。

标签: java hashmap equals hashcode


【解决方案1】:

您的代码将工作 - 但使用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());
}

【讨论】:

  • 谢谢乔恩,我会调查的。
  • 非常感谢。关于数组语法:我觉得我正在为那个人打一场失败的战斗:P
  • @lynks:你到底为什么想要将类型信息分成两部分?变量的类型是“字符串数组”——如果这是一个旧的 C 或 C++ 习惯,那么值得抛弃在新语言中没有意义的约定。
  • 我完全明白,其实内心深处我知道我错了。我想我只是不喜欢在一个地方看到 [] ,然后在索引数组时在另一个地方看到。是的,这是一个古老的 C 习惯。
  • @lynks:嗯,他们在做非常不同的事情——一个是索引一个数组,一个是说你感兴趣的类型 一个数组。就个人而言,我真的不喜欢 Java 甚至允许“拆分”语法这一事实。哎哟。
【解决方案2】:

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

来自HashMap#put的Java文档

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

【讨论】:

  • 谢谢,重大的脑力衰竭时刻。我整个星期都在与各种Collections 合作。 当然 values.equals() 无关紧要,都是关于钥匙的!
【解决方案3】:

您的代码非常好。您将字符串映射到整数。没有任何重复。

【讨论】:

    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

      这是一个特定于字符串的计数器,它应该被泛化并具有 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();
          }
      }
      

      【讨论】:

      • 当 OP 写了一段 4 行做同样事情的代码时,为什么要这么做?
      • 根据我的经验,使用对象可以更轻松地进行编程。
      • 还演示了如何在查看结果时按键顺序进行迭代。
      【解决方案6】:

      您的代码对我来说看起来不错,没有问题。由于 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);
      }
      

      以下代码

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

      会打印出来。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-25
        • 1970-01-01
        • 1970-01-01
        • 2021-11-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多