HashMap中的密钥存在检查

ath*_*ena 298 java hashmap

是否总是需要在HashMap中检查密钥是否存在?

我有一个HashMap,说1000条目,我正在寻求提高效率.如果非常频繁地访问HashMap,那么在每次访问时检查密钥是否存在将导致很大的开销.相反,如果密钥不存在并因此发生异常,我可以捕获异常.(当我知道这种情况很少发生时).这将减少对HashMap的访问一半.

这可能不是一个好的编程习惯,但它会帮助我减少访问次数.或者我在这里遗漏了什么?

[ 更新 ]我在HashMap中没有空值.

Jon*_*eet 498

你有没有存储空值?如果没有,你可以这样做:

Foo value = map.get(key);
if (value != null) {
    ...
} else {
    // No such key
}
Run Code Online (Sandbox Code Playgroud)

否则,如果返回null值,则可以检查是否存在:

Foo value = map.get(key);
if (value != null) {
    ...
} else {
    // Key might be present...
    if (map.containsKey(key)) {
       // Okay, there's a key but the value is null
    } else {
       // Definitely no such key
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 虽然作为示例可能更清楚,但您也可以为第二部分编写“if(value!=null || map.containsKey(key))”。至少如果你想以任何一种方式做同样的事情——没有重复的代码。由于[短路](https://en.wikipedia.org/wiki/Short- Circuit_evaluation),它会起作用。 (2认同)

Col*_*ert 65

通过检查密钥是否存在,您将无法获得任何收益.这是代码HashMap:

@Override
public boolean containsKey(Object key) {
    Entry<K, V> m = getEntry(key);
    return m != null;
}

@Override
public V get(Object key) {
    Entry<K, V> m = getEntry(key);
    if (m != null) {
        return m.value;
    }
    return null;
}
Run Code Online (Sandbox Code Playgroud)

只需检查返回值get()是否不同null.

这是HashMap源代码.


资源:

  • 显示这些方法的一个具体实现有什么意义? (2认同)
  • 为了解释这一点,在大多数情况下,检查密钥存在与获取值大约需要相同的时间.因此,在获取值之前,不会优化任何内容来检查实际存在的密钥.我知道这是一种概括,但它有助于理解. (2认同)
  • 正如在接受的答案中指出的那样,这个问题是完全错误的.当然,您可以通过检查比较值的关键存在来获得某些东西 - 您可以将不存在的键与存在的键区分开,但将其映射为null作为值. (2认同)

Dea*_*mer 40

更好的方法是使用HashMap的containsKey方法.明天soembody将向地图添加null,你应该区分key和key具有null值.


jkf*_*kff 22

你是说你有像这样的代码

if(map.containsKey(key)) doSomethingWith(map.get(key))

到处都是 ?然后你应该检查是否map.get(key)返回null,就是这样.顺便说一下,HashMap不会为丢失的密钥抛出异常,而是返回null.唯一containsKey需要的情况是,当您存储空值时,要区分空值和缺失值,但这通常被认为是不好的做法.


Mik*_*man 7

只是containsKey()为了清晰起见.它速度快,保持代码清洁和可读性.整点HashMaps是该键查找速度快,只需确保hashCode()equals()正确实施.


naz*_*ris 5

You can also use the computeIfAbsent() method in the HashMap class.

In the following example, map stores a list of transactions (integers) that are applied to the key (the name of the bank account). To add 2 transactions of 100 and 200 to checking_account you can write:

HashMap<String, ArrayList<Integer>> map = new HashMap<>();
map.computeIfAbsent("checking_account", key -> new ArrayList<>())
   .add(100)
   .add(200);
Run Code Online (Sandbox Code Playgroud)

This way you don't have to check to see if the key checking_account exists or not.

  • If it does not exist, one will be created and returned by the lambda expression.
  • 如果存在,则将返回该键的值computeIfAbsent()

真的很优雅!