Перейти к основному содержимому

Использование Java-класса Map.Entry

· 4 мин. чтения

1. Обзор

Мы часто используем карты для хранения набора пар ключ-значение. Затем, в какой-то момент, нам часто нужно перебирать их .

В этом руководстве мы сравним различные методы итерации карты, выделив, когда может быть полезно использовать Map.Entry . Затем мы узнаем, как можно использовать Map.Entry для создания кортежа. Наконец, мы создадим упорядоченный список кортежей.

2. Оптимизация итерации карты

Предположим, что у нас есть карта названий книг с именем автора в качестве ключа:

Map<String, String> map = new HashMap<>();

map.put("Robert C. Martin", "Clean Code");
map.put("Joshua Bloch", "Effective Java");

Давайте сравним два метода получения всех ключей и значений из нашей карты.

2.1. Использование Map.keySet

Во-первых, рассмотрите следующее:

for (String key : bookMap.keySet()) {
System.out.println("key: " + key + " value: " + bookMap.get(key));
}

Здесь цикл перебирает набор ключей . Для каждого ключа мы получаем соответствующее значение с помощью Map.get . Хотя это очевидный способ использовать все записи на карте, для каждой записи требуется две операции — одна для получения следующего ключа и одна для поиска значения с помощью get .

Если нам нужны только ключи на карте, keySet — хороший вариант. Однако есть более быстрый способ получить как ключи, так и значения.

2.2. Использование Map.entrySet вместо этого

Давайте перепишем нашу итерацию, чтобы использовать entrySet :

for (Map.Entry<String, String> book: bookMap.entrySet()) {
System.out.println("key: " + book.getKey() + " value: " + book.getValue());
}

В этом примере наш цикл проходит по коллекции объектов Map.Entry . Поскольку Map.Entry хранит и ключ, и значение вместе в одном классе, мы получаем их оба в одной операции .

Те же правила применяются к использованию потоковых операций Java 8 . Потоковая передача через entrySet и работа с объектами Entry более эффективны и могут потребовать меньше кода.

3. Работа с кортежами

Кортеж — это структура данных с фиксированным количеством и порядком элементов. Мы можем думать о Map.Entry как о кортеже, который хранит два элемента — ключ и значение. Однако, поскольку Map.Entry — это интерфейс, нам требуется класс реализации. В этом разделе мы рассмотрим одну реализацию, предоставляемую JDK: AbstractMap.SimpleEntry .

3.1. Создание кортежа

Сначала рассмотрим класс Book :

public class Book {
private String title;
private String author;

public Book(String title, String author) {
this.title = title;
this.author = author;
}
...

Далее создадим кортеж Map.Entry с ISBN в качестве ключа и объектом Book в качестве значения:

Map.Entry<String, Book> tuple;

Наконец, давайте создадим экземпляр нашего кортежа с помощью AbstractMap.SimpleEntry :

tuple = new AbstractMap.SimpleEntry<>("9780134685991", new Book("Effective Java 3d Edition", "Joshua Bloch"));

3.2. Создание упорядоченного списка кортежей

При работе с кортежами часто полезно иметь их в виде упорядоченного списка.

Во-первых, мы определим наш список кортежей:

List<Map.Entry<String, Book>> orderedTuples = new ArrayList<>();

Во-вторых, давайте добавим несколько записей в наш список:

orderedTuples.add(new AbstractMap.SimpleEntry<>("9780134685991", 
new Book("Effective Java 3d Edition", "Joshua Bloch")));
orderedTuples.add(new AbstractMap.SimpleEntry<>("9780132350884",
new Book("Clean Code","Robert C Martin")));

3.3. Сравнение с картой

Чтобы сравнить различия с Map , давайте добавим новую запись с уже существующим ключом:

orderedTuples.add(new AbstractMap.SimpleEntry<>("9780132350884", 
new Book("Clean Code", "Robert C Martin")));

Во-вторых, мы пройдемся по нашему списку, отображая все ключи и значения:

for (Map.Entry<String, Book> tuple : orderedTuples) {
System.out.println("key: " + tuple.getKey() + " value: " + tuple.getValue());
}

Наконец, давайте посмотрим на вывод:

key: 9780134685991 value: Book{title='Effective Java 3d Edition', author='Joshua Bloch'}
key: 9780132350884 value: Book{title='Clean Code', author='Robert C Martin'}
key: 9780132350884 value: Book{title='Clean Code', author='Robert C Martin'}

Обратите внимание, что у нас могут быть повторяющиеся ключи, в отличие от базовой карты , где каждый ключ должен быть уникальным. Это связано с тем, что мы использовали реализацию List для хранения наших объектов SimpleEntry , что означает, что все объекты независимы друг от друга.

3.4. Списки объектов входа

Следует отметить, что Entry не предназначен для использования в качестве универсального кортежа. Классы библиотеки часто предоставляют для этой цели универсальный `` класс Pair .

Однако мы можем обнаружить, что нам нужно временно работать со списками записей при подготовке данных для Карты или извлечении данных из нее.

4. Вывод

В этой статье мы рассмотрели Map.entrySet как альтернативу перебору ключей карты.

Затем мы рассмотрели, как Map.Entry можно использовать в качестве кортежа.

Наконец, мы создали список упорядоченных кортежей, сравнивая различия с базовой картой .

Как всегда, код примера доступен на GitHub .