Reputation: 437
Regarding Map.Entry
, the Java documentation states:
A map entry (key-value pair). The
Map.entrySet
method returns a collection-view of the map, whose elements are of this class. The only way to obtain a reference to a map entry is from the iterator of this collection-view. TheseMap.Entry
objects are valid only for the duration of the iteration; more formally, the behavior of a map entry is undefined if the backing map has been modified after the entry was returned by the iterator, except through thesetValue
operation on the map entry.
This suggests that iterating over a Map is read-only. If operations on Map objects (such as put()
etc.) are undefined, how does one bulk-update entries in a Map?
Upvotes: 0
Views: 87
Reputation: 21490
The code
Map<String, String> myMap = new HashMap<>(Map.of("a", "b"));
for (Map.Entry<String, String> entry: myMap.entrySet()) {
entry.put("foo", "foo");
}
doesn't compile because entry
is a Map.Entry
and Map.Entry
doesn't have a put()
method.
The fragment
Map<String, String> myMap = new HashMap<>(Map.of("a", "b"));
for (Map.Entry<String, String> curEntry: myMap.entrySet()) {
myMap.put("foo", "foo");
// the behavior of curEntry is undefined after the preceding line
}
is the case the Map.Entry
documentation mentions: myMap
is modified while iterating over it. That means that according to the documentation the behavior of curEntry
is undefined after the modifying line.
Please note that modifying the map while iterating over it also leads to unspecified behavior for the iterator:
If the map is modified while an iteration over the set is in progress (except through the iterator's own
remove
operation, or through thesetValue
operation on a map entry returned by the iterator) the results of the iteration are undefined.
The fragment
Map<String, String> myMap = new HashMap<>(Map.of("a", "b"));
Map<String, String> otherMap = new HashMap<>(Map.of("c", "d"));
for (Map.Entry<String, String> entry: myMap.entrySet()) {
otherMap.put("foo", "foo");
}
is OK because this code modifies otherMap
while iterating over myMap
. Since these are two different Map
s this is allowed.
Bulk-Updating a Map
while iterating over it:
Map<String, Integer> myMap = new HashMap<>(Map.of("a", 1));
for (Map.Entry<String, Integer> entry: myMap.entrySet()) {
entry.setValue(m.getValue() + 1);
}
is OK, because this code uses the supported Map.Entry.setValue()
method to update the value of an entry.
Upvotes: 2