[英]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.