Руководство по EnumMap

Руководство по EnumMap

1. обзор

EnumMap - это упрощениеMap , которое использует исключительноEnum в качестве ключей.

В этом руководстве мы обсудим его свойства, распространенные варианты использования и когда его следует использовать.

2. Настройка проекта

Представьте себе простое требование, когда нам нужно сопоставить дни недели со спортом, в который мы играем в этот день:

Monday     Soccer
Tuesday    Basketball
Wednesday  Hiking
Thursday   Karate

Для этого мы могли бы использовать перечисление:

public enum DayOfWeek {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

Что, как мы скоро увидим, станет ключевым для нашей карты.

3. Творчество

Чтобы начать исследоватьEnumMap, сначала нам нужно создать его экземпляр:

EnumMap activityMap = new EnumMap<>(DayOfWeek.class);
activityMap.put(DayOfWeek.MONDAY, "Soccer");

И вот наше первое отличие от чего-то более распространенного, напримерHashMap. Обратите внимание, что сHashMap параметризации типа достаточно, что означает, что мы можем обойтись сnew HashMap<>(). However, EnumMap requires the key type in the constructor.

3.1. EnumMap Copy Конструктор

EnumMap также поставляется с двумя конструкторами копирования. Первый берет ещеEnumMap:

EnumMap activityMap = new EnumMap<>(DayOfWeek.class);
activityMap.put(DayOfWeek.MONDAY, "Soccer");
activityMap.put(DayOfWeek.TUESDAY, "Basketball");

EnumMap activityMapCopy = new EnumMap<>(dayMap);
assertThat(activityMapCopy.size()).isEqualTo(2);
assertThat(activityMapCopy.get(DayOfWeek.MONDAY)).isEqualTo("Soccer");
assertThat(activityMapCopy.get(DayOfWeek.TUESDAY)).isEqualTo("Basketball");

3.2. Map Copy Конструктор

Или,if we have a non-empty Map whose key is an enum, then we can do that, too:

Map ordinaryMap = new HashMap();
ordinaryMap.put(DayOfWeek.MONDAY, "Soccer");

EnumMap enumMap = new EnumMap(ordinaryMap);
assertThat(enumMap.size()).isEqualTo(1);
assertThat(enumMap.get(DayOfWeek.MONDAY)).isEqualTo("Soccer");

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

Если указанная карта содержит более одного типа перечисления, конструктор выдастClassCastException.

4. Добавление и получение элементов

После созданияEnumMap мы можем добавить наш вид спорта с помощью методаput():

activityMap.put(DayOfWeek.MONDAY, "Soccer");

И чтобы получить его, мы можем использоватьget():

assertThat(clubMap.get(DayOfWeek.MONDAY)).isEqualTo("Soccer");

5. Проверка на наличие элементов

Чтобы проверить, определено ли у нас отображение для конкретного дня, мы используемcontainsKey():

activityMap.put(DayOfWeek.WEDNESDAY, "Hiking");
assertThat(activityMap.containsKey(DayOfWeek.WEDNESDAY)).isTrue();

И, чтобы проверить, сопоставлен ли конкретный вид спорта с какой-либо клавишей, мы используемcontainsValue():

assertThat(activityMap.containsValue("Hiking")).isTrue();

5.1. null как значение

Теперьnull является семантически допустимым значением дляEnumMap.

Давайте свяжемnull с «ничего не делая» и сопоставим его с субботой:

assertThat(activityMap.containsKey(DayOfWeek.SATURDAY)).isFalse();
assertThat(activityMap.containsValue(null)).isFalse();
activityMap.put(DayOfWeek.SATURDAY, null);
assertThat(activityMap.containsKey(DayOfWeek.SATURDAY)).isTrue();
assertThat(activityMap.containsValue(null)).isTrue();

6. Удаление элементов

Чтобы отменить отображение определенного дня, мы простоremove() это:

activityMap.put(DayOfWeek.MONDAY, "Soccer");
assertThat(activityMap.remove(DayOfWeek.MONDAY)).isEqualTo("Soccer");
assertThat(activityMap.containsKey(DayOfWeek.MONDAY)).isFalse();

Как мы видим,remove(key) возвращает предыдущее значение, связанное с ключом, илиnull , если для ключа не было сопоставления.

Мы также можем выбратьunmap a particular day only if that day is mapped to a particular activity:

activityMap.put(DayOfWeek.Monday, "Soccer");
assertThat(activityMap.remove(DayOfWeek.Monday, "Hiking")).isEqualTo(false);
assertThat(activityMap.remove(DayOfWeek.Monday, "Soccer")).isEqualTo(true);

remove(key, value) удаляет запись для указанного ключа, только если ключ в настоящее время сопоставлен с указанным значением.

7. Просмотры коллекции

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

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

EnumMap activityMap = new EnumMap(DayOfWeek.class);
activityMap.put(DayOfWeek.THURSDAY, "Karate");
activityMap.put(DayOfWeek.WEDNESDAY, "Hiking");
activityMap.put(DayOfWeek.MONDAY, "Soccer");

7.1. valuesс

Первое представление нашей карты действий -values() w, которое, как следует из названия, возвращает все значения на карте:

Collection values = dayMap.values();
assertThat(values)
  .containsExactly("Soccer", "Hiking", "Karate");

Обратите внимание, чтоEnumMap  - это упорядоченная карта. Он использует порядокDayOfWeek enum для определения порядка записей.

7.2. keySetс

Точно так жеkeySet() возвращает коллекцию ключей, снова в порядке перечисления:

Set keys = dayMap.keySet();
assertThat(keys)
        .containsExactly(DayOfWeek.MONDAY, DayOfWeek.WEDNESDAY, DayOfWeek.SATURDAY);

7.3. entrySetс

Наконец,entrySet() возвращает сопоставление в парах ключ и значение:

assertThat(dayMap.entrySet())
    .containsExactly(
        new SimpleEntry(DayOfWeek.MONDAY, "Soccer"),
        new SimpleEntry(DayOfWeek.WEDNESDAY, "Hiking"),
        new SimpleEntry(DayOfWeek.THURSDAY, "Karate")
    );

Упорядочивание на карте, безусловно, может пригодиться, и в нашем руководстве мы углубимся вcompares TreeMap to HashMap.

7.4. переменчивость

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

activityMap.put(DayOfWeek.TUESDAY, "Basketball");
assertThat(values)
    .containsExactly("Soccer", "Basketball", "Hiking", "Karate");

Наоборот; любые изменения, которые мы вносим во вспомогательные виды, будут отражены в исходной карте действий:

values.remove("Hiking");
assertThat(activityMap.containsKey(DayOfWeek.WEDNESDAY)).isFalse();
assertThat(activityMap.size()).isEqualTo(3);

По контрактуEnumMap с синтерфейсомMap подвиды поддерживаются исходной картой.

8. Когда использоватьEnumMap

8.1. Спектакль

ИспользованиеEnum в качестве ключа позволяет выполнить дополнительную оптимизацию производительностиlike a quicker hash computation since all possible keys are known in advance.

Простота использованияenum в качестве ключа означает, что дляEnumMap нужно только создать резервную копию простой старой JavaArray с очень простой логикой для хранения и поиска. С другой стороны, общие упрощенияMap должны учитывать проблемы, связанные с использованием универсального объекта в качестве ключа. Например,HashMap https: //www.example.com/java-hashmap [требует сложной структуры данных и значительно более сложной логики хранения и извлечения], чтобы учесть возможность коллизии хешей.

8.2. функциональность

Кроме того, как мы видели,EnumMap  - это упорядоченная карта, в которой ее представления будут повторяться в порядке перечисления. Чтобы получить аналогичное поведение для более сложных сценариев, мы можем посмотретьTreeMap илиLinkedHashMap.

9. Заключение

В этой статье мы рассмотрели реализациюEnumMap интерфейсаMap. При работе сEnum  как ключ,EnumMap can пригодится.

Полный исходный код для всех примеров, используемых в этом руководстве, можно найти в папкеGitHub project.