7

我在我的教科书中找到了这个程序,它基本上计算了字符串数组 tst 中每个字符串的出现次数。

public class Test {
private static HashMap<String, Integer> mp = new HashMap<String, Integer>();

public static void main(String[] args) {
    String[] tst = new String[] { "ABC", "DEF", "DEF", "DEF","ABC", "DEF", "ABC" };
    checkMap(tst);

}

public static void checkMap(String[] str) {
    for (String st : str) {
        if (!mp.containsKey(st)) {
            mp.put(st, 1);
        }

        else {
            Integer ct = mp.get(st);
            if(ct!=null)
            {
            ct++;
            mp.put(st, ct);
            }
        }
    }

    for (Map.Entry<String, Integer> entry : mp.entrySet()) {
        System.out.println(entry.getKey() + " ocurrs " + entry.getValue()+ " times");
    }
}

}

代码的输出是 -

ABC ocurrs 3 times
DEF ocurrs 4 times

我的问题在这里的 if/else 语句中-

if (!mp.containsKey(st)) {
            mp.put(st, 1);
        }

        else {
            Integer ct = mp.get(st);
            if(ct!=null)
            {
            ct++;
            mp.put(st, ct);
            }
        }

当我们没有在 hashmap 中放置任何条目(hashmap 为空)时,这在什么基础上起作用?如果这是一个非常基本的问题,我深表歉意,但我在网上找不到任何解释这一点的答案。我对 if/else 循环中写的内容感到困惑。另外,这里的这条线 -

Integer ct = mp.get(st);

当哈希图实际上是空的时,我们如何获得键映射到的值?我试图将其与数组相关联 - 如果您在创建数组但未初始化后查询数组的元素,它会抛出一个空指针。有人,请解释一下这对哈希图是如何工作的。再次为提出这样一个基本问题而道歉。

4

5 回答 5

5

好吧,在这一行中,您检查地图是否包含键

if (!mp.containsKey(st)) {

由于!表达式之前有一个,这意味着“如果地图不包含键”。之后,“then”块会跟随您在映射中插入带有值的键1(因为它不存在)。

否则,如果键确实存在(else块),则获取该键的值,将其递增(ct++)并再次将其添加到同一键的映射中。

我只想说,if(ct!=null)此代码不需要空检查 ( )。


关于这个问题的一般评论:

当哈希图实际上是空的时,我们如何获得键映射到的值?

如果您尝试从HashMap映射中不存在的键中获取某些内容,则映射返回null. 对于您尝试从空地图获取的任何键都是如此。


你能解释一下这是什么意思吗 -Integer ct = mp.get(st);

map.get(key)返回为该键存储的值。映射本身是键值对的集合,这意味着:对于每个键,映射中都有一个值。因此,要获取为您调用的该键存储的值map.get(key)。如果您存储map.put("ABC", 10)地图将返回10map.get("ABC")

于 2013-06-22T10:15:12.413 回答
1
  1. 这是因为 containsKey 函数检查 hashMap 是否包含特定键。
  2. 如果 HashMap 是 mpty 并且您尝试获取不存在的键,您将获得空值
于 2013-06-22T10:15:58.543 回答
0

空值检查不是必需的。要么键包含在映射中且其值不为空,要么不包含在映射中。

我们可以确信该值永远不会为 null 的原因是地图(及其所有内容)已在方法中定义和使用,并且 null 没有机会将其带到那里。

虽然get()如果传递了一个不包含的键,该方法将返回 null,但此代码永远不会发生这种情况。

无论如何,代码是不优雅的:所有这些行都可以表示为一个简单的行:

mp.put(mp.containsKey(st) ? mp.get(st) + 1 : 1);
于 2013-06-22T10:15:24.237 回答
0

考试:

if (!mp.containsKey(st))

测试该键是否在地图中没有条目。

因此,在else分支中,条目存在并且具有非空值是合乎逻辑的......这使得ct == null测试变得多余。

当值存在时,代码get()是现有值,向它加 1(实际上它创建了一个新值,Integer但那是另一回事)并put()返回新值。

请注意,该代码混合了自动装箱和非自动装箱。mp.put(st, 1)自动装箱;幕后确实如此mp.put(st, new Integer(1))

相似地:

Integer ct = mp.get(st);
ct++;

是真的:

Integer ct = mp.get(st);
Integer tmp = new Integer(ct.intValue() + 1);
ct = tmp;
于 2013-06-22T10:15:24.790 回答
0

stfor (String st : str)循环到这里的。它与 . 无关HashMap

if (!mp.containsKey(st)) {

这将测试 是否HashMap包含notkey st。如果没有项目,它显然不能包含密钥。然后在else它使用的块mp.get(st)中,现在总是会成功,因为它已被检查mp包含st(实际上,它不包含它)。

在这里进行空检查if (ct == null),因为如果出于某种原因,地图包含null有问题的键。但是,如果代码仅将整数放入映射并测试键是否存在,则这是不可能的,因此可以删除空检查。

于 2013-06-22T10:16:03.207 回答