Вложенные интерфейсы в Java на примере `Map.Entry`
Разбираюсь с коллекциями и мапами, обнаружил вложенный интерфейс Map.Entry.
Chat GPT подсказал, что внутри этот интерфейс выглядит так:
public interface Map<K, V> {
interface Entry<K, V> {
K getKey();
V getValue();
}
// ...
}
И вот тут моих знаний не хватает: я вижу один интерфейс и вложенный в него второй интерфейс, но не вижу реализаций ни того, ни другого.
Я могу использовать методы вложенного интерфейса Map.Entry, но мне нигде не требуется его имплементировать.
Я могу использовать как все методы, так и некоторые из них, и ошибкой это не будет.
Помогите разобраться с тем, что интерфейс использовать можно, но не нужно его имплементировать и реализовывать все его методы.
Ответы (1 шт):
Позволю немного расширить комментарий Станислава Володарского.
Практически каждый класс, реализующий интерфейс Map, использует свою собственную реализацию интерфейса Map.Entry, а то и несколько, при этом как правило классы-реализации являются как минимум непубличными, то есть непосредственный доступ к ним ограничен.
Некоторые классы-реализации интерфейса java.util.Map и соответствующие им реализации вложенного интерфейса Map.Entry
java.util:AbstractMap: публичные классыAbstractMap.SimpleEntryиAbstractMap.SimpleImmutableEntry;- Метод
Map.entry()(Java 9+), который используется для создания иммутабельных мап при помощи фабричных методовMap.of/Map.ofEntries, возвращает в качестве реализации экземпляры непубличного классаKeyValueHolder; EnumMap: приватныйEnumMap.EntryIterator.Entry;HashMap: непубличныйHashMap.Node;Hashtable: приватныйHashtable.Entry;LinkedHashMap: непубличныйLinkedHashMap.Entry;TreeMap: непубличныйTreeMap.Entry;Properties(реализация интерфейсаMap<Object, Object>, фактически класс-обёртка надConcurrentHashMap):ConcurrentHashMap.MapEntry;
java.util.concurrent:ConcurrentHashMap: непубличныйConcurrentHashMap.Node(для внутреннего хранения) иConcurrentHashMap.MapEntry;ConcurrentSkipListMap: непубличныйConcurrentSkipListMap.Node(для внутреннего хранения) и упомянутыйAbstractMap.SimpleImmutableEntry
В целом, всё вышеприведённое может служить наглядным объяснением, почему следует использовать публичный интерфейс / контракт Map.Entry<K,V>, а не его многочисленные реализации (принцип инверсии зависимостей в SOLID) -- в данном случае, детали реализаций не имеют особого значения.