在使用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 };)