哈希映射包含键

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

当我们还没有在哈希映射表中放入任何条目(哈希映射表为空)时,它是基于什么工作的?如果这是一个非常基本的问题,那么请原谅,但我找不到任何在线解释这个问题的答案。我对if/else循环中的内容感到困惑。 此外,这里是一行代码 -

Integer ct = mp.get(st);

当HashMap实际上是空的时,我们如何获取键被映射到的值呢? 我试图将此与数组相关联 - 如果查询创建但未初始化的数组的元素,则会抛出空指针异常。 请有人解释一下对于HashMap如何工作。 再次道歉,因为提出了这样一个基本的问题。

5个回答

6

好的,在这行代码中,你需要检查地图是否包含一个键

if (!mp.containsKey(st)) {

由于表达式之前有一个“!”,这意味着“如果映射不包含键”。然后,在“then”块中,您将插入具有值1的键(因为它不存在)。
否则,如果该键存在(“else”块),您将获取该键的值,将其增加(“ct ++”),然后再次将其添加到具有相同键的映射中。
让我说一下,此代码的空检查(“if(ct!= null)”)对此代码不必要。
关于此问题的一般评论:
如何在实际上哈希图为空时获取键映射的值?
如果您尝试从未出现在地图中的密钥获取某些内容,则地图将返回null。对于您尝试从空地图获取的任何密钥,都是如此。
请解释一下这是什么意思 - Integer ct = mp.get(st);
map.get(key)返回存储在该键中的值。映射本身是键值对的集合,这意味着:对于每个键,映射中都有一个值。因此,要获取存储在该键中的值,您调用map.get(key)。如果您存储map.put(“ABC”,10),则对于map.get(“ABC”),地图将返回10。

谢谢@darijan。你能解释一下这句话的意思吗——Integer ct = mp.get(st)?我特别想了解这个语句(正如我在问题中所解释的)。 - user2341013

1
  1. 这是因为containsKey函数检查HashMap是否包含特定的键。
  2. 如果HashMap为空并且您尝试获取不存在的键,则会返回null值。

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;

0

null检查是必要的。要么键包含在地图中且其值不为空,要么键不包含在地图中。

我们可以对值永远不为null感到自信的原因是该映射(及其所有内容)在方法中被定义和使用,并且没有机会使null进入其中。

虽然get()方法会返回null,如果传递给它一个它不包含的键,但这段代码永远不会发生。

总之,这段代码不够优雅:所有那些行都可以表达为一行简单的语句:

mp.put(mp.containsKey(st) ? mp.get(st) + 1 : 1);

0

st 是由循环 for (String st : str) 获取的,它与 HashMap 没有任何关系。

if (!mp.containsKey(st)) {

这个测试检查 HashMap 是否 包含键 st。如果没有任何项,它显然不能包含该键。然后在 else 块中,它使用 mp.get(st),现在它总是成功的,因为已经检查到 mp 包含 st(实际上,它不包含它)。

空值检查 if (ct == null) 在这里是因为如果由于某种原因地图包含了问题键的 null。然而,如果代码只将整数放入映射并测试键的存在,则不应该可能出现这种情况,因此可以删除空值检查。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接