Answers:
您是否存储了空值?如果没有,您可以执行以下操作:
Foo value = map.get(key);
if (value != null) {
...
} else {
// No such key
}
否则,如果返回空值,则可以检查是否存在:
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
}
}
get
很好,并且在需要该值时也避免进行两次查找。
通过检查密钥是否存在,您将不会获得任何收益。这是以下代码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;
}
只需检查的返回值get()
是否不同于即可null
。
这是HashMap源代码。
资源:
更好的方法是使用的containsKey
方法HashMap
。明天有人会在地图上添加null。您应该区分键的存在和键的值为空。
null
在一起。
只是containsKey()
为了清楚起见。它速度很快,并保持代码的清洁和可读性。HashMap
s 的全部要点是密钥查找是快速的,只需确保hashCode()
和equals()
正确实现即可。
您也可以computeIfAbsent()
在HashMap
类中使用该方法。
在下面的示例中,map
存储应用于密钥(银行帐户名称)的交易(整数)列表。要添加的2个交易100
,并200
以checking_account
可以这样写:
HashMap<String, ArrayList<Integer>> map = new HashMap<>();
map.computeIfAbsent("checking_account", key -> new ArrayList<>())
.add(100)
.add(200);
这样,您不必检查密钥是否checking_account
存在。
computeIfAbsent()
。真的很优雅!👍
乔恩·斯凯特(Jon Skeet)的答案以有效的方式很好地解决了两种情况(带有null
价值和没有null
价值的地图)。
关于数字条目和效率问题,我想补充一点。
我有一个带有1.000个条目的HashMap,并且我正在考虑提高效率。如果HashMap的访问非常频繁,则每次访问时检查密钥是否存在将导致大量开销。
包含1.000个条目的地图不是很大的地图。
以及具有5.000或10.000条目的地图。
Map
设计用于以这种尺寸进行快速检索。
现在,假定hashCode()
映射键提供了良好的分布。
如果您可以使用Integer
as作为键类型,请执行此操作。
它的hashCode()
方法非常有效,因为唯一int
值不可能发生冲突:
public final class Integer extends Number implements Comparable<Integer> {
...
@Override
public int hashCode() {
return Integer.hashCode(value);
}
public static int hashCode(int value) {
return value;
}
...
}
如果对于键,您必须使用另一种内置类型String
,例如经常在中使用的类型,则Map
可能会发生一些冲突,但是从中的1000个对象到数千个对象Map
,则该String.hashCode()
方法应该很少提供良好的分布。
如果您使用自定义类型,请覆盖hashCode()
并equals()
正确进行设置,并确保总体hashCode()
提供合理的分布。
您可以参考的第9项Java Effective
。
这里有一个帖子,详细介绍了道路。