[英]java.util.Map values() method performance
我有一张这样的地图,其中包含几百万个条目:
private final Map<String, SomeItem> tops = new HashMap<>();
我需要获取值列表,这可以通过调用java.util.Map values()
方法来完成。
问题 :
每次我调用此方法时都会创建值集合,或者它是预先计算的,从性能角度来看,它可以保存多次以进行调用?
问题是在我的情况下Map
有数百万个元素,并且我不想每次调用values()
都创建新列表
以下是java.util.HashMap
中Map.values()
的复制实现:
public Collection<V> values() {
Collection<V> vs = values;
if (vs == null) {
vs = new Values();
values = vs;
}
return vs;
}
这清楚地表明,除非有必要,否则不会创建值集合。 因此,不应因调用values()
而造成额外的开销
这里重要的一点可能是: 没关系!
但是首先,请参考到目前为止的其他答案:在这里返回的集合通常是“缓存的”,因为它是惰性创建的,然后,将返回相同的实例。 例如,考虑HashMap
类中的实现:
public Collection<V> values() {
Collection<V> vs;
return (vs = values) == null ? (values = new Values()) : vs;
}
甚至在AbstractMap
类的文档 (大多数Map
实现基于该文档 )中指定了(作为合同的一部分,作为实现规范):
该集合是在第一次调用此方法时创建的,并响应于所有后续调用而返回。 没有执行同步,因此有几次机会对该方法的多次调用不会全部返回相同的集合。
但是现在,有人可能会说实施可能会在以后更改。 HashMap
类的实现可以更改,或者可以切换到另一种不扩展AbstractMap
且以不同方式实现的Map
实现。 当前这样实现的事实本身(本身)并不能保证它总是这样实现。
因此,更重要的一点(以及无关紧要的原因)是, values()
方法确实应该返回一个集合视图 。 如Map
接口文档中所述 :
Map界面提供了三个集合视图 ,这些视图允许将地图的内容作为一组键,一组值或一组键-值映射来查看。
特别是Map#values()
方法的文档 :
返回此映射中包含的值的Collection视图。 集合由地图支持,因此对地图的更改会反映在集合中,反之亦然。
我无法想象实现包含处理Map
所有值的视图的合理方法。
例如,假设HashMap
中的实现是这样的:
public Collection<V> values() {
return new Values();
}
然后,它将在每次调用时返回一个新的集合。 但是创建此集合根本不涉及处理值。
或这样说:调用此方法的成本与地图的大小无关 。 无论地图包含10个元素还是10000个元素,它基本上都需要创建单个对象。
正如其他人提到的那样,您可以通过查看代码来看到这一点。 您还可以编写一个快速示例来向自己证明。 下面的代码将打印正确的10次,因为对象标识的值始终相同。
public static void main(String[] args) {
Map<String, String> myMap = new HashMap();
Collection<String> lastValues = myMap.values();
for (int i=0; i < 10; i++) {
System.out.println(lastValues == myMap.values());
lastValues = myMap.values();
}
}
下面的代码将在第一次打印true,然后在接下来的9次false。
public static void main(String[] args) {
Map<String, String> myMap = new HashMap();
Collection<String> lastValues = myMap.values();
for (int i=0; i < 10; i++) {
System.out.println(lastValues == myMap.values());
lastValues = myMap.values();
myMap = new HashMap();
}
}
阅读此主题后,还有一个建议,如果Map顶部声明的内容未更改-您可以使用google guava ImmutableMap对象。 有关更多信息-UnmodifiableMap(Java Collections)与ImmutableMap(Google)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.