2011-04-28 177 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。