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.