2011-04-28 218 views
10

Map.putAll等同於在地圖上調用Map.put(k, v)一旦從密鑰k每個映射到值v在指定映射的。所以在功能方面,兩者都是一樣的。Map.put和Map.putAll方法之間的區別?

所以,我很好奇,想知道什麼是其他方面的差異,以及何時使用哪一種呢?

回答

4

使用putAll(Map)當你有一個你想要添加到你的地圖的幾個值的地圖,並且當你想要添加到你的地圖中的一個或幾個值時使用put(K,V)

putAll(Map)在大多數實現中,只需在循環中調用put(K,V),即可閱讀source

+3

最後一行有點誤導。雖然AbstractMap _does_按照您的描述工作,但其他具體的Map實現不會。 – 2011-04-28 09:36:38

+0

@Paul:+1,你說得對。這有點簡化,但我相信大多數符合Map接口的實現都是這樣工作的,因爲Map接口沒有提供那麼多的餘地。 – 2011-04-28 11:22:30

1

putAll() method

Copies all the elements from a specified map to the current Map object.  

put() method

Adds an element at a specific key entry to a Map object. 
5

如在文檔中指出:

Map.put

將指定值與 指定鍵此映射 (可選操作)。如果地圖 先前包含 密鑰的映射,則舊值將由 指定值替換。 (A地圖m爲 所述包含鍵k的映射,當且僅 如果m.containsKey(K)將返回 真。)

允許把在圖中的單個鍵 - 值對。

Map.putAll

將所有從 指定映射到此地圖(可選 操作)的映射。此呼叫的作用是 相當於調用的穿上這地圖(V K, )一旦爲每個映射 從密鑰k到值v在指定 地圖。此操作的行爲是不確定的 如果指定的地圖是 操作的同時修改是在 進展。

放從一個地圖到另一個地圖的所有數據。


時使用哪一個?

如果你想從一個地圖複製完整的數據,其他的你可以使用map.putAll否則你可以簡單地添加使用map.put一個鍵 - 值對。


Map.putAll等同於 調用Map.put的(K,V)地圖一次 用於從密鑰k在指定映射每個映射到值v 上。因此與 功能方面都相同。

無論您何時實現hasmap地圖,然後到一個地圖複製到另一個使用投入(K,V)將採取更多的努力,可以說使用的putAll(M),我們可以用一個拷貝一行地圖或多種編碼碼。

0

Map.put(Object key, Object value)允許您將單個條目添加到Map.putAll(Map t)將所有包含在地圖t中的條目添加到指定的地圖。 putAll()在組合兩個Maps時非常有用。

4

由於Map只是一個接口,在沒有任何實現的情況下,除了功能差異之外,putAll和重複put之間不會有任何差別,即沒有差異。如果您查看Map的各個實現(例如HashMap),則可能存在性能問題。一個put至少應該像重複放置一樣有效,但它可能完全相同。

+3

+1 - 你打敗了我......你回答了OP的問題,而不是僅僅背誦API的細節。 – 2011-04-28 09:16:15

9

它..取決於。

putputAll的接口方法,所以真正實現該接口將保證,該put方法把一個鍵/值對在地圖上得到控制而putAll會把所有鍵/值對從源頭。

但是這取決於實施者如何做到這一點,以及除了(內部)做什麼。

當然,一個簡單的實現將調用put源圖的每一個條目,但也許有人發明了另一種方法來實現目標。或者putAll會在輸入添加對之前/之後做一些其他地圖內部的東西。

我的拇指規則:如果必須將所有鍵/值對從一張地圖放到另一張地圖上,那麼請依靠實現者的智能性並使用putAll方法。與手動調用put相比,它總有一個很好的機會提供更好的性能。

2

最明顯的區別是同步收藏。

對於同步處理的地圖,putAll會將所有條目添加爲單個操作。如果您有兩個線程嘗試將所有具有不同值的相同鍵全部輸入,則只會獲得一組完整的值。即來自第一或第二線程,但不是某種組合。

如果您在兩個線程中重複使用put(),則可以獲得可能不是有效組合的值的任意組合。


我看到/實現了put()和putAll()的事務操作。當putAll是事務性的時候,所有或沒有鍵/值將被添加。例如如果某個鍵或值由於某種原因無法添加。如果使用put(),則只會停止個別密鑰/值(可能還有未添加的任何值),執行潛在的不完整更新。

1

當使用putAll而不是put時,我看到巨大的性能優勢。 請參見下面的示例程序:

公共類SampleTest {

public static void main(final String[] args) { 

    final Map<String, String> testMap = new HashMap<>(); 
    final Map<String, String> testMap2 = new HashMap<>(); 

    final LocalDateTime startTestTime = LocalDateTime.now(); 
    for(int i=0; i < 1000000; i++) { 
     testMap.put(i+"", i+""); 
    } 
    final LocalDateTime endTestTime = LocalDateTime.now(); 
    System.out.println("<<<<<<<<<Time for put>>>>>>>>>>>"); 
    System.out.println(ChronoUnit.MILLIS.between(startTestTime, endTestTime)); 

    final LocalDateTime startTestTime1 = LocalDateTime.now(); 
    testMap2.putAll(testMap); 
    final LocalDateTime endTestTime1 = LocalDateTime.now(); 
    System.out.println("<<<<<<<<<Time for put all>>>>>>>>>>>"); 
    System.out.println(ChronoUnit.MILLIS.between(startTestTime1, endTestTime1)); 
} 

}

這返回(毫秒):

<<<<<<<<<Time for put>>>>>>>>>>> 
1934 
<<<<<<<<<Time for put all>>>>>>>>>>> 
116 

結論: 的putAll()肯定更比使用下面的免責聲明更高效。 1.此結果在我的機器上(即取決於機器配置)。但你仍然看到很大的差異。 2.如上所述Map是一個接口,所以性能取決於實現,我已經考慮到了HashMap的廣泛使用。 所以如果性能是一個約束,你可以更喜歡putAll()爲HashMap atleast。