Map.putAll
is equivalent to that of calling Map.put(k, v)
on the map once for each mapping from key k to value v in the specified map. So with the functional aspect, both are same.
开发者_如何学GoSo, I am curious to know what are the other differences and when to use which one?
Well, it depends.
put
and putAll
are interface methods, so every real implementation of that interface will guarantee, that the put
method puts a single key/value pair in the map while putAll
will put all key/value pairs from the source.
But it's up to the implementor how to do it and what to do in addition (internally).
Sure, a trivial implementation would call put
for each and every entry of the source map, but maybe someone invents another method to achieve the goal. Or putAll
will do some other map internal stuff before/after/while entering adding pairs.
My rule of a thumb is: if you have to put all key/value pairs from one map to another, then rely on the smartness of the implementor and use the putAll
method. There's always a good chance that it provides a better performance than calling put
for all pairs manually.
As stated in docs:
Map.put
Associates the specified value with the specified key in this map (optional operation). If the map previously contained a mapping for the key, the old value is replaced by the specified value. (A map m is said to contain a mapping for a key k if and only if m.containsKey(k) would return true.)
Allows you to put a single key-value pair in map.
Map.putAll
Copies all of the mappings from the specified map to this map (optional operation). The effect of this call is equivalent to that of calling put(k, v) on this map once for each mapping from key k to value v in the specified map. The behavior of this operation is undefined if the specified map is modified while the operation is in progress.
put all data from one map to another map.
when to use which one?
If you want to copy complete data from one map to other you can use map.putAll
else you can simply add one key-value pair using map.put
.
Map.putAll is equivalent to that of calling Map.put(k, v) on the map once for each mapping from key k to value v in the specified map. So with functional aspect both are same.
No when you implement map in hasmap then to copy one map to another using put(k,v) will take more effort and you can say more coding using putAll(m) we can copy map with a single line code.
Use putAll(Map)
when you have a Map of several values that you want to add to your Map, and use put(K,V)
when you have a one or a couple of values you want to add to your Map.
putAll(Map)
in most implementations just calls put(K,V)
in a loop, read the source.
Since Map is just an interface, without any implementation, there cannot be any difference between a putAll and a repeated put, except in what you call the functional aspect. In other words: there can't be any difference. However, if you look at individual implementations of Map (e.g. HashMap) there may be differences in performance. One putAll should be at least as efficient as a repeated put for any reasonable implementation, but it may be just exactly the same.
The most obvious difference is the synchronized collections.
For a synchornized map, putAll will add all entries as a single operation. If you have two threads attempting to putAll the same keys with different values, you will only get one complete set of values. i.e. either from the first or second thread, but not some combination.
If you use put() repeatedly in two threads, you can get any combination of values being retained which may not be a valid combination.
I have seen/implemented transactional operations for put() and putAll(). When putAll is transactional, all or none key/values will be added. e.g. if a key or value cannot be added for some reason. If you are using put() only the indiviudal key/value (and possibly any not added) will be stopped, performing a potentially incomplete update.
I see a huge performance benefit when using putAll instead of put. See the sample program below:
public class 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));
}
}
This returns (in Milliseconds):
<<<<<<<<<Time for put>>>>>>>>>>>
1934
<<<<<<<<<Time for put all>>>>>>>>>>>
116
Conclusion: putAll() is definitely more performant than put() with the below disclaimers. 1. This result is on my machine (i.e depends on the machine configuration). But you still see a wide difference. 2. As metioned above Map is an interface, so the performance will depend on the implementation, i have considered HashMap as it is widely used. So if performance is a constraint you can prefer putAll() for HashMap atleast.
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.
Map.put(Object key, Object value)
allows you to add a single entry into the while Map.putAll(Map t)
adds all entries contained in the Map t to the specified Map. putAll() is useful while combining two Maps.
精彩评论