2

While iterating Map<> using for loop

for(Map.Entry<K,V> mapEntry : myMap.entrySet()){
    // something
}

I found entrySet() method returns a set of Entry<K,V>

so it has add(Entry<K,V> e) method

then I created a class which implements Map.Entry<K,V> and tried inserting the object like below

    public final class MyEntry<K, V> implements Map.Entry<K, V> {

    private final K key;
    private V value;

    public MyEntry(K key, V value) {
        this.key = key;
        this.value = value;
    }

    @Override
    public K getKey() {
        return key;
    }

    @Override
    public V getValue() {
        return value;
    }

    @Override
    public V setValue(V value) {
        V old = this.value;
        this.value = value;
        return old;
    }

}


Entry<String, String> entry = new MyEntry<String, String>("Hello", "hello");
myMap.entrySet().add(entry); //line 32

there is no compilation error, but it throws a runtime error

    Exception in thread "main"
java.lang.UnsupportedOperationException
    at java.util.AbstractCollection.add(AbstractCollection.java:262)
    at com.seeth.AboutEntrySetThings.main(AboutEntrySetThings.java:32)

4 Answers4

4

From the JavaDoc on entrySet() method:

The set supports element removal, which removes the corresponding mapping from the map, via the Iterator.remove, Set.remove, removeAll, retainAll and clear operations. It does not support the add or addAll operations.

Ivan Kulezic
  • 440
  • 4
  • 15
1

The problem is that you are calling add() method on the entrySet() of HashMap and there is no such implementation in that class, only in its superclasses.

From HashMap source code:

public Set<Map.Entry<K,V>> entrySet() {
    Set<Map.Entry<K,V>> es;
    return (es = entrySet) == null ? (entrySet = new EntrySet()) : es;
}

final class EntrySet extends AbstractSet<Map.Entry<K,V>> {
// there is no add() override
}

Because add() method is not overriden (neither in HashMap.EntrySet, nor in AbstractSet), a method from AbstractCollection will be used, which has the following definition:

public boolean add(E e) {
    throw new UnsupportedOperationException();
}

Also, looking on the entrySet() Javadoc:

(...) The set supports element removal, which removes the corresponding mapping from the map, via the Iterator.remove, Set.remove, removeAll, retainAll and clear operations. It does not support the add or addAll operations.

syntagma
  • 23,346
  • 16
  • 78
  • 134
0

The javadoc for that method https://docs.oracle.com/javase/10/docs/api/java/util/AbstractCollection.html#add(E) says

This implementation always throws an UnsupportedOperationException.

Then subclasses override it and public void add(int size, E element); The subclass EntrySet in HashMap does not override it.

pamcevoy
  • 1,136
  • 11
  • 15
0

Method java.util.HashMap.entrySet() returns a class java.util.HashMap.EntrySet, which itself does not implement method Set.add().
To add an object to the collection, you must use method myMap.put(entry.getKey(), entry.getValue()).

Method entrySet() is used only for reading data, and not for modification.

Ilya
  • 720
  • 6
  • 14