Perhaps because Map#values returns a representation of the values supported by the map .
From the official value of Java-Doc of Map # :
Gets a view of the collection of values โโcontained in this map. The collection is supported by the map, so changes to the map are reflected in the collection, and vice versa. [...] The collection supports the removal of elements, which removes the corresponding map from the map, through the operations Iterator.remove, Collection.remove, removeAll, keepAll and clear. It does not support add or addAll operations.
Please note that the AbstractMap class, from which most map implementations are distributed, has an additional field transient volatile Collection<V> values , and this is what you get there. Since you see that the collection is used internally by the Card, and therefore changes to it are also reflected on the card itself. See Also: AbstractMap Source Code
If you want to dwell in detail, take a look at the AbstractMap#values method in the source code. There they create a collection of values โโas a wrapper that runs on the original map. For example, its next method iterates over Entry<K, V> Map entries, but returns them only with Entry#getValue , etc.
In addition, the remove method, as you can see, is passed to the Entry<K, V> iterator, so at the end the end will be executed on the original map.
source share