Interface Map.Entry<K,V>
The returned comparator is serializable and throws NullPointerException when comparing an entry with a null key.
comparingByValue
The returned comparator is serializable and throws NullPointerException when comparing an entry with null values.
comparingByKey
The returned comparator is serializable if the specified comparator is also serializable.
comparingByValue
The returned comparator is serializable if the specified comparator is also serializable.
Report a bug or suggest an enhancement
For further API reference and developer documentation see the Java SE Documentation, which contains more detailed, developer-targeted descriptions with conceptual overviews, definitions of terms, workarounds, and working code examples.
Java is a trademark or registered trademark of Oracle and/or its affiliates in the US and other countries.
Copyright © 1993, 2021, Oracle and/or its affiliates, 500 Oracle Parkway, Redwood Shores, CA 94065 USA.
All rights reserved. Use is subject to license terms and the documentation redistribution policy.
Name already in use
JBook / collections / map / intro.md
- Go to file T
- Go to line L
- Copy path
- Copy permalink
- Open with Desktop
- View raw
- Copy raw contents Copy raw contents
Copy raw contents
Copy raw contents
Как уже было сказано во введении, интерфес java.util.Map не имеет отношения к интерфейсу java.util.Collection , однако формально является коллекцией.
По сути, это коллекция пар ключ -> значение, а java.util.Map это интерфейс ассоциативного массива. Каждому ключу соответствует некоторое значение. Иногда реализации java.util.Map называют ‘мапами’, хэш-таблицами, в Python же это и вовсе словари .
Название Map появилось как сокращение слова mapping , что значит отображение , соответствие .
В интерфейсе java.util.Map параметризуются два типа, это ключ и значение.
Объявление java.util.Map выглядит как:
При этом стоит отметить, что не может быть повторяющихся ключей, что следует из названия и смысла Map : каждому ключу соответствует значение.
Вопрос:
Почему бы тогда не назвать просто словарь , как в Python ?
Ответ:
На самом деле в Java существует абстрактный класс java.util.Dictionary еще с версии 1.0 , который сейчасс уже давно не используется.
И до этого иерархия как раз и была основана на классе java.util.Dictionary , например, как одна из старых реализаций хэш-таблицы — java.util.HashTable .
Класс java.util.Dictionary является полностью абтрактным, без какого-либо состояния.
Но благодаря WORA в Java просто так ничего не меняют и не удаляют, поэтому старые классы остались, а новую иерархию начали строить с интерфейсов.
Интерфейс java.util.Map появился в Java начиная с версии 1.2 .
Основные методы, которые предоставляет интерфейс java.util.Map :
- V get(Object key)
- V put(K key, V value)
- int indexOf(Object element)
- V remove(Object key)
- Set<K> keySet()
- Collection<V> values()
- Set<Map.Entry<K, V>> entrySet()
Это значит, что все реализации интерфейса java.util.Map позволяют доставать, добавлять и удалять элементы по ключам, а также предоставлять множество ключей и коллекцию хранимых значений.
Отдельного рассмотрения заслуживает последний метод: Set<Map.Entry<K, V>> entrySet() .
Как уже было сказано выше, Map это набор пар ключ-значение.
Так вот интерфейс, описывающий поведение такой пары, называется Entry .
Объявление java.util.Map#Entry выглядит как:
И предоставляет методы, позволяющие получить/установить ключ и значение.
Единственное, что может быть здесь интересно — это то, что setValue в отличии от канонических setter- ов возвращает старое замененное значение.
Помимо всего прочего предоставляются также компараторы для сравнения пар по ключу и значению.
У каждого класса, реализующего интерфейс java.util.Map своя реализация java.util.Map#Entry , но большинство из них основано на стандартной реализации, которая объявлена у java.util.HashMap .
Объявление выглядит следующим образом:
В этой реализации нет каких-то подводных камней и сложностей, кроме того, что она объявлена с модификатором доступа package . Ее использование ограничено в рамках пакета, в классе которого она объявлена, т.е java.util .
Стандартная реализация, доступная для использования везде, объявлена у java.util.AbstractMap и называется SimpleEntry .
Объявление выглядит следующим образом:
Там же объявлена и неизменяемая реализация SimpleImmutableEntry . Также существуют сторонние реализации java.util.Map#Entry , например, в библиотеке Apache Commons .
Иерархия классов выглядит следующим образом:
Абстрактный класс java.util.AbstractMap предоставляет заготовку для последующих реализаций.
В нем уже определены некоторые методы, достаточные для неизменяемой структуры данных, но такие методы как put кидают исключение java.lang.UnsupportedOperationException .
Что говорит о том, что операция не поддерживется и ее надо либо не использовать, либо переопределить метод.
Наиболее известные реализации java.util.Map :
-
— основана на хэш-таблицах. — расширение предыдущей реализации на основе двусвязных списков. — основана на красно-черном дереве.
Существует также реализация java.util.HashTable , но она уже давно не используется, во многом благодаря тому, что большинство методов в ней является synchronized , что губительо сказывается на производительности.
Когда и какую реализацию выбрать?
Если порядок хранения элементов не важен, то выбор java.util.HashMap более чем оправдан.
Данная реализация предоставляет отличную производительность работы с базовыми методами(добавление, поиск, удаление): O(1) , но при условии отсутствия коллизий, т.е хорошо определенной хэш-функции добавляемых элементов, в Java за это отвечает метод hashCode.
В случае, если порядок добавления элементов важен, то стоит рассмотреть java.util.LinkedHashMap . Понятно, что за сохранение порядка надо платить, поэтому данная реализация работает медленнее, чем java.util.HashMap .
Минусом может также являться то, что и java.util.HashMap , и java.util.LinkedHashMap занимают в памяти больше места, чем хранят элементов, в отличии от java.util.TreeMap .
Если необходимо, чтобы элементы были отсортированы, то следует присмотреться к java.util.TreeMap . Однако в таком случае добавляемые элементы должны либо реализовывать интерфейс java.lang.Comparable , либо необходимо написать свой собственный компаратор.
Помните, что java.util.TreeMap не поддерживает работу с null ключами.
| Структура данных | Производительность (basic ops) | Память | Отсортированность элементов | Работа с null |
|---|---|---|---|---|
| Treemap | O(log(N)) | Без издержек | В естественном порядке | Недопустимы null ключи, без ограничений на null значения |
| HashMap | O(1) | С издержками | Неотсортирован | Допустим null ключ, без ограничений на null значения |
| Linked HashMap | O(1) (но медленнее HashMap) | Также как и в HashMap | В порядке добавления | Допустим null ключ, без ограничений на null значения |
Реализации java.util.Map имеют встроенные итераторы. Получить можно как список всех ключей keySet() или всех значений values() , так и все пары ключ-значение entrySet() .
При этом следует помнить, что порядок гарантируеутся не всеми реализациями, как например в примере выше.
Стоит помнить, что, как и в случае с итерированием сипсков, если в ходе работы итератора структура данных была изменена (без использования методов итератора), то будет выброшено исключение:
Избежать этого можно удаляя элемент с помощью итератора, с которым происходит работа:
Map entry java что это
Map.Entry interface in Java provides certain methods to access the entry in the Map. By gaining access to the entry of the Map we can easily manipulate them. Map.Entry is a generic and is defined in the java.util package.
Declaration :
Methods:
-
equals (Object o) – It compares the object (invoking object) with the Object o for equality.
Syntax :
Иерархия Map
Map, как ты знаешь, хранит набор пар «ключ-значение». Ключи должны быть уникальны, значения – любые. Если ты добавляешь в Map пару ключ-значение, а такой ключ в коллекции уже есть, то старое значение заменится на новое. Т.е. ключ – это что-то вроде уникального индекса, который может быть любым объектом.
Как только название Map ни переводится на русский язык. Версий уже существует, наверное, десятка полтора. Самые распространённые – это Словарь, Карта, Отображение, …
Название Map – это математический термин, который обозначает набор (множество) пар (x,y), где каждому уникальному x соответствует какой-то y.
Программисты очень любят Map, поэтому у нас тут аж 4 различных коллекции, реализующих интерфейс java Map:
Вот тебе ее простенькая структура наследования:
Желтым отмечено, что Entry – это вложенный интерфейс в интерфейсе Map.
Entry был добавлен, чтобы описать именно пару элементов как одну сущность.
Вот какие методы есть у Map<K,V>:
| Методы | Описание |
|---|---|
| int size() | Возвращает количество пар в map. |
| boolean isEmpty() | Проверяет, пустой ли map. |
| boolean containsKey(Object key) | Содержит ли map заданный ключ? |
| boolean containsValue(Object value) | Содержит ли map заданное значение? |
| V get(Object key) | Возвращает значение по ключу. |
| V put(K key, V value) | Устанавливает новое значение ключу. Метод возвращает старое значение или null |
| putAll(Map<? extends K, ? extends V> m) | Добавляет пары из другого map. |
| void clear() | Очищает map – удаляет все пары. |
| Set<K>keySet() | Возвращает Set из ключей. |
| Collection<V>values() | Возвращает коллекцию из значений. |
| Set<Map.Entry<K, V>>entrySet() | Возвращает множество (Set) пар. |
K,V – это типы-параметры для ключей (Key) и значений(Value).
— Ну, с большинством методов я знаком, хотя работал только с некоторыми из них.
А что еще за Entry такой?
— Это класс, который описывает пару элементов. Методов у него немного:
| Методы | Описание |
|---|---|
| K getKey() | Возвращает значение «ключа пары». |
| V getValue() | Возвращает значение «значения пары». |
| V setValue(V value) | Устанавливает новое значение «значения пары». |
Entry удобен тем, что ты можешь взять какую-то пару и передать ее в нужный метод, не передавая туда всю коллекцию map.
— Ну и пробегусь еще по реализациям Map.
Первая на очереди – это коллекция HashMap. Она использует хэш-таблицы для хранения элементов. Ключи и значения могут быть любых типов, а также могут быть null. Порядок элементов может меняться при изменении коллекции.
Элементы хранятся внутри HashMap в виде набора групп – корзин (bucket). В какую корзину попадет элемент — зависит от значения его hashCode().
Очень грубо говоря, элементы со значением хэш-кода от 1 до 100 попадают в первую корзину, со значением от 101 до 200 — во вторую, и т.д.
Смысл такого хранения в том, что при поиске/удалении можно отбрасывать ненужные корзины, и исключать все их элементы из рассмотрения.
— Есть очень хорошая статья по HashMap, советую почитать http://habrahabr.ru/post/128017/
Вторая коллекция – это LinkedHashMap. Основное ее отличие от HashMap – она дополнительно хранит элементы в виде связного списка. У обычной HashMap порядок элементов неопределён и, строго говоря, может меняться со временем. А у LinkedHashMap можно получить итератор и с помощью него перебрать все элементы в порядке их добавления в LinkedHashMap. Так же у LinkedHashMap есть итератор, который позволяет обойти все пары в порядке из последнего использования/активности.
Есть очень хорошая статья по LinkedHashMap, держи http://habrahabr.ru/post/129037/
Третья коллекция, о которой я бы хотела сегодня рассказать – это TreeMap.
TreeMap хранит свои элементы отсортированными по возрастанию. Это достигается благодаря тому, что TreeMap для их хранения использует сбалансированное красно-черное бинарное дерево.
Благодаря этому там очень низкое время вставки и поиска элементов. Этот класс – отличный выбор при использовании очень больших объемов данных.
Что я еще не рассказала?
— WeakHashMap, но мне Риша рассказывал про него пару дней назад.
— Ну, когда рассказывала про SoftReference, WeakReference и PhantomReference.
— Верю, учитывая, что ты все правильно назвал. Тогда иди отдыхай. Вечером увидимся.