This article is participating in “Java Theme Month – Java Debug Notes Event”, see < Event link > for more details.
This article is an original article
Question origin
When translating StackOverFlow, I found two problems:
How does Java generate a HashMap as “straightforward” as Python
How can I remove elements from a Collection in an iterative Collection loop without ConcurrentModification
But I discovered a problem when I tried the following answers.
When I put together the solution code for the above two problems, which is to generate the HashMap directly and remove the Map elements with an iterator
public static void main(String[] args) {
Map<String,String> map = Map.of("a"."b"."a2"."b2");
for (varit = map.entrySet().iterator(); it.hasNext();) {vartest =it.next(); map.remove(test.getKey()); }}Copy the code
The result error
Exception in thread "main" java.lang.UnsupportedOperationException
at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:127)
at java.base/java.util.ImmutableCollections$AbstractImmutableMap.remove(ImmutableCollections.java:910)
at My.main(My.java:10)
Copy the code
Problem solving
The error message probably said that this Collection could not be modified, so I immediately checked the source code
/ / of definition
static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2) {
return new ImmutableCollections.MapN<>(k1, v1, k2, v2);
}
/ / MapN definition
static final class MapN<K.V> extends AbstractImmutableMap<K.V>
//AbstractImmutableMapdefineabstract static class AbstractImmutableMap<K.V> extends AbstractMap<K.V> implements Serializable {
@Override public void clear(a) { throw uoe(); }
@Override public V compute(K key, BiFunction<? super K,? super V,? extends V> rf) { throw uoe(); }
@Override public V computeIfAbsent(K key, Function<? super K,? extends V> mf) { throw uoe(); }
@Override public V computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> rf) { throw uoe(); }
@Override public V merge(K key, V value, BiFunction<? super V,? super V,? extends V> rf) { throw uoe(); }
@Override public V put(K key, V value) { throw uoe(); }
@Override public void putAll(Map<? extends K,? extends V> m) { throw uoe(); }
@Override public V putIfAbsent(K key, V value) { throw uoe(); }
@Override public V remove(Object key) { throw uoe(); }
Copy the code
You can see that the Map generated by “of” is not a HashMap but a Subclass of AbstractImmutableMap. In AbstractImmutableMap, the remove() method is a direct throw Exception.
conclusion
Attention should be paid to the Map) of () and Map) ofEntries. () are ImmutableCollections MapN < >;
This might be different from the normal mutable HashMap we want.