8 ноября 2023
Тэги: Collections, Java, ООП.
В статье SequencedCollection и SequencedSet в Java мы рассмотрели интерфейс SequencedCollection, который появился в Java 21. Также узнали про его более частный случай – интерфейс SequencedSet.
Теперь перейдём к интерфейсу SequencedMap, который обладает сходным функционалом, но не входит напрямую в иерархию SequencedCollection.
Этот интерфейс расширяет стандартный Map, добавляя в него методы для доступа и манипулирования первым и последним элементами. В отличие от SequencedCollection, здесь мы манипулируем не отдельными значениями, а сразу парой «ключ-значение», представленной Map.Entry.
Помимо этого, мы можем отдельно получать множество упорядоченных ключей и упорядоченных значений. Ну и уже привычный нам метод reversed(), который позволяет обходить мапу в обратном порядке.
По аналогии с SequencedSet, интерфейс SequencedMap поддерживается классами LinkedHashMap и TreeMap. При этом HashMap не поддерживает интерфейс SequencedMap, потому что изначально не гарантирует порядок.
Упрощённая иерархия классов и интерфейсов, связанных с SequencedMap, представлена на этой схеме:
Если мы возьмём за основу LinkedHashMap, то метод putLast(), добавляющий элемент в конец мапы, будет действовать аналогично стандартному put(), т.к. данный вид мапы сохраняет порядок добавления. В начало мапы в любой момент можно добавить с помощью putFirst().
Для вывода содержимого мапы в обратном порядке используем метод reversed().
Класс TreeMap хоть и поддерживает интерфейс SequencedMap, но не поддерживает методы добавления первого и последнего элемента, т.к. этот вид мапы всегда сортирует ключи в алфавитном порядке, а потому сам «знает», какой элемент должен быть «первым», а какой – «последним».
При попытке вызвать метод putFirst() или putLast() мы получим UnsupportedOperationException. Поэтому в TreeMap добавление элементов делаем через старый добрый put().
Удаление элементов мы делаем с помощью методов pollFirstEntry() и pollLastEntry(). Они удаляют элемент из мапы и возвращают его в качестве результата. Если мапа будет пустая, они не кидают ошибку и просто возвращают null.
И здесь особой разницы между LinkedHashMap и TreeMap нет, поскольку для TreeMap тоже всегда известен «первый» и «последний» элемент.
Для получения первого и последнего элементы мы используем методы getFirstEntry() и getLastEntry().
Если мапа пустая, методы будут возвращает null так же, как и при удалении. Поэтому разницы между LinkedHashMap и TreeMap здесь нет.
Как и в случае с обычной мапой, мы можем получать по отдельности упорядоченные ключи, значения или коллекцию Map.Entry, которая также поддерживает порядок.
Методы sequencedKeySet() и sequencedEntrySet() возвращают упорядоченные множества SequencedSet. Метод sequencedValues() возвращает упорядоченный список SequencedCollection.
Мы рассмотрели особенности интерфейса SequencedMap и убедились, что концептуально он похож на SequencedCollection. При этом два интерфейса не связаны напрямую иерархией наследования. SequencedMap предоставляет удобный набор методов для работы с упорядоченными ключами и значениями мапы.
Kotlin, Java, Spring, Spring Boot, Spring Data, SQL, PostgreSQL, Oracle, Linux, Hibernate, Collections, Stream API, многопоточность, файлы, Nginx, Apache, maven, gradle, JUnit, YouTube, новости, руководство, ООП, алгоритмы, головоломки, rest, GraphQL, Excel, XML, json, yaml.