在使用map.get()时使用java Map.containsKey()是多余的

我一直在想,在最佳实践中是否允许使用java.util.Map上的containsKey()方法,而不是对get()的结果进行空检查。

我的理由是,查看值的两次似乎是多余的 – 首先为containsKey() ,然后再为get()

另一方面, Map大多数标准实现可能会caching最后一次查找,或者编译器可以以其他方式取消冗余,并且为了代码的可读性,最好维护containsKey()部分。

我非常感谢您的意见。

在这种情况下,如果get(key)返回null ,则某些Map实现允许具有空值(例如HashMap get(key) ,但不保证与此关键字关联的映射中没有条目。

所以,如果你想知道一个地图是否包含一个键使用Map.containsKey 。 如果你只需要一个映射到一个键的值使用Map.get(key)Map.containsKey将是无用的,会影响性能。 而且,在并发访问映射(例如ConcurrentHashMap )的情况下,在testingMap.containsKey(key)有可能在调用Map.get(key)之前,该条目将被另一个线程删除。

我认为这是相当标准的写:

 Object value = map.get(key); if (value != null) { //do something with value } 

代替

 if (map.containsKey(key)) { Object value = map.get(key); //do something with value } 

它的可读性不高,效率稍高,所以我没有看到有任何理由不这样做。 显然, 如果你的映射可以包含null,那么这两个选项就不具有相同的语义

正如assylias指出的,这是一个语义问题。 一般来说,Map.get(x)== null是你想要的,但有些情况下使用containsKey很重要。

一个这样的情况是一个caching。 我曾经在一个Web应用程序的性能问题上工作过,这个应用程序频繁地查询数据库,寻找不存在的实体。 当我研究该组件的caching代码时,我意识到它正在查询数据库是否cache.get(key)== null。 如果数据库返回null(实体未find),我们将caching该键 – > null映射。

切换到containsKey解决了这个问题,因为映射到一个空值实际上意味着什么。 关键映射为null与不存在的关键字具有不同的语义含义。

我们可以使@assylias回答更具可读性的Java8可选,

 Optional.ofNullable(map.get(key)).ifPresent(value -> { //do something with value };)