Java - Зачем использовать EnumMap, когда сам enum может использоваться как карта? - PullRequest
1 голос
/ 28 марта 2020

Я недавно читал Java. Итак, у меня есть перечисление ниже, которое действует как карта с ключом "JESS IE" и значением "Мой любимый кот".

Так зачем кому-то использовать EnumMap? Спасибо

public enum Cat {
    JESSIE("My favorite cat");

    private String description;

    Cat(String description){
        this.description = description;
    }
}

Ответы [ 2 ]

2 голосов
/ 28 марта 2020

enum - это ключ в EnumMap, и поэтому эти две вещи совершенно разные. У вас нет возможности узнать все виды вещей, которые вы можете захотеть связать со своими кошками.

description может быть неотъемлемой частью Cat, но вы можете захотеть связать кошек с их слугами или где они (в настоящее время) живут или какова их предпочтительная еда (в настоящее время).

EnumMap<Cat, Human> catsServant;
EnumMap<Cat, House> catsHome;
EnumMap<Cat, Meal> catsFood;

Так как вам не нужно изменять Cat, чтобы связать его с другим объектом, это делает его большим проще в использовании, и ваше перечисление стало бы огромным, если бы вы заполнили его всеми возможными вещами, с которыми вы, возможно, захотите связать своих кошек.

Вторая проблема заключается в том, что enum s являются синглетонами, что означает, что если вы поместите изменяемое состояние (настоятельно не рекомендуется!) В ваш Cat, добавив setDescription(String) метод, это изменит это глобально в вашей программе. Это может не иметь значения для простых программ или простых свойств, таких как description, но имеет значение, когда у вас более сложный код.

Теперь более реалистичный c пример. Перечисление JDK TimeUnit имеет такие значения, как MINUTE, и создатели не могли знать обо всех возможных вещах, которые люди могут захотеть связать с ними. Однако с EnumMap я могу предоставить перевод на свой родной язык следующим образом:

EnumMap<TimeUnit, String> xlate = new EnumMap<>(TimeUnit.class);
xlate.put(TimeUnit.MINUTE, "Minuutti");
xlate.put(TimeUnit.SECOND, "Sekunti");

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

A связанный вопрос - вот почему существует специальное EnumMap, так как вы также можете использовать карту нормалей, такую ​​как HashMap<Cat, Human>.

2 голосов
/ 28 марта 2020

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

В качестве примера рассмотрим другой класс Human следующим образом

@AllArgsConstructor
static class Human {
    String name;
}

Теперь вы могли бы искать Cat для сопоставления его владельца, но какой смысл было бы сохранять весь объект Human, на который ссылаются для такое отображение? Несмотря на то, что вы могли сохранить такую ​​ссылку, для возможности запроса полезно сохранить такую ​​ссылку в дополнительной структуре данных EnumMap, в данном случае -

EnumMap<Cat, Human> enumMap = new EnumMap<>(Cat.class);
enumMap.put(Cat.JESSIE, new Human("naman"));
enumMap.put(Cat.LUCY, new Human("user"));
...