Метод add() для entrySet() в Map<>
Во время итерации Map<>
используя для цикла
for(Map.Entry<K,V> mapEntry : myMap.entrySet()){
// something
}
я нашел entrySet()
метод возвращает набор Entry<K,V>
так оно и есть add(Entry<K,V> e)
метод
Затем я создал класс, который реализует Map.Entry<K,V>
и попытался вставить объект, как показано ниже
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
нет ошибки компиляции, но выдает ошибку времени выполнения
Exception in thread "main"
java.lang.UnsupportedOperationException
at java.util.AbstractCollection.add(AbstractCollection.java:262)
at com.seeth.AboutEntrySetThings.main(AboutEntrySetThings.java:32)
4 ответа
С JavaDoc на entrySet()
метод:
Набор поддерживает удаление элементов, которое удаляет соответствующее отображение с карты с помощью операций Iterator.remove, Set.remove, removeAll, retainAll и clear. Он не поддерживает операции добавления или добавления.
Метод java.util.HashMap.entrySet() возвращает класс java.util.HashMap.EntrySet, который сам не реализует метод Set.add ().
Чтобы добавить объект в коллекцию, вы должны использовать метод myMap.put(entry.getKey(), entry.getValue()).
Метод entrySet () используется только для чтения данных, а не для модификации.
Проблема в том, что вы звоните add()
метод на entrySet()
из HashMap
и нет такой реализации в этом классе, только в его суперклассах.
От HashMap
исходный код:
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
}
Так как add()
метод не переопределен (ни в HashMap.EntrySet
ни в AbstractSet
), метод из AbstractCollection
будет использоваться, который имеет следующее определение:
public boolean add(E e) {
throw new UnsupportedOperationException();
}
Кроме того, глядя на entrySet()
Javadoc:
(...) Набор поддерживает удаление элементов, которое удаляет соответствующее отображение с карты с помощью операций Iterator.remove, Set.remove, removeAll, retainAll и clear. Он не поддерживает операции добавления или добавления.
В Javadoc для этого метода https://docs.oracle.com/javase/10/docs/api/java/util/AbstractCollection.html говорится
Эта реализация всегда генерирует исключение UnsupportedOperationException.
Затем подклассы переопределяют его и public void add(int size, E element);
Подкласс EntrySet
в HashMap
не отменяет это.