Map接口在1.8中新增了一个默认方法getOrDefault(Object key, V defaultValue)
意思是返回map中对应key的value值,如果map中没有传入的key,那么返回传入的defaultValue
需格外注意,在使用中人潜意识会以为在从map中get(key)的返回值为null就会最终返回defaultValue,
这种说法是不对的,有一种特殊情况,当map中存在这个key,但对应的value值为null时,getOrDefault会返回null,而不会返回defaultValue
defaultValue只有当map中不存在这个key时才会返回
接下来看方法源码:
default V getOrDefault(Object key, V defaultValue) {
V v;
return (((v = get(key)) != null) || containsKey(key))
? v
: defaultValue;
}
这就引申出另一个问题,根据上面的方法使用思路,源码不应该这样写吗?
default V getOrDefault(Object key, V defaultValue) {
return containsKey(key) ? get(key): defaultValue;
}
我在第一次使用这个方法时查看了这个方法的源码,思考了许久,为何要使用
(((v = get(key)) != null) || containsKey(key))
这种判断形式?
现在讲下我个人看法:
首先||是 或 运算符,大家应该都知道,当两个条件有一个为true时,最终结果就为true,但有一个细节,当左边的子条件表达式为true,右边的子表达式将不会再进行运算,整个||表达式就会返回一个true.
此时回过头来看这两段源码,或无疑问,他们的调用结果都是相同的,那么jdk开发人员为何不按常理去写呢?我想是因为效率问题,在大多数应用场景下,从map中根据key去获取对应的value,一般key存在的情况居多,key不存在的情况少.
那么回过头来看这两段的代码,对于大多数key存在的情况,jdk源码只需调用一个表达式中的一个方法get(key)后做个等值判断就可返回结果,而第二段代码,需要先调用containsKey(key),然后在调用 get(key)返回结果.这样jdk源码在大多数情况下就提升了map的查询效率.