Enum (перечислення) у Java – це спеціальний тип доданий у Java 5, який використовується для визначення колекцій констант. Точніше кажучи Enum – це особливий тип класу Java. Enum може містити константи, поля, методи.

Зміст:

  1. Приклад Enum
  2. Enum в операторах if
  3. Enum в операторах switch
  4. Ітерація Enum
  5. Метод Enum toString()
  6. Метод Enum valueOf()
  7. Поля Enum
  8. Методи Enum
  9. Абстрактні методи Enum
  10. Реалізація інтерфейсу в Enum
  11. EnumSet
  12. EnumMap
  13. Додаткові особливості Enum у Java

Приклад Enum

Розглянемо простий приклад Enum Java:

public enum Level {
    HIGH,
    MEDIUM,
    LOW
}

Для оголошення Enum, замість ключового слова class використовується ключове слово enum.

Звернення до констант з вищенаведеного Enum відбувається наступним чином:

Level level = Level.HIGH;

Слід додати, що у цьому випадку змінна повинна мати тип Level, котрий є Enum типом Java. В якості значення змінна level може приймати одну з констант перечислення Level (HIGH, MEDIUM або LOW).

Enum в операторах if

Приклад використання Enum в операторі if:

public enum Level {
    HIGH,
    MEDIUM,
    LOW
}

public class Main {

    public static void main(String[] args) {
        printLevel(Level.LOW); // Level Low
        printLevel(Level.HIGH); // Level High
    }

    public static void printLevel(Level level) {
        if(level == Level.HIGH) {
            System.out.println("Level High");
        } else if(level == Level.MEDIUM) {
            System.out.println("Level Medium");
        } else if(level == Level.LOW) {
            System.out.println("Level Low");
        }
    }
}

Enum в операторах switch

Приклад використання Enum в операторі switch:

public enum Level {
    HIGH,
    MEDIUM,
    LOW
}

public class Main {

    public static void main(String[] args) {
        printLevel(Level.LOW); // Level Low
        printLevel(Level.HIGH); // Level High
    }

    public static void printLevel(Level level) {
        switch (level) {
            case HIGH -> System.out.println("Level High");
            case MEDIUM -> System.out.println("Level Medium");
            case LOW -> System.out.println("Level Low");
            default -> System.out.println("Unknown Level");
        }
    }
}

Ітерація Enum

Щоб отримати масив усіх значень Enum у Java, можна викликан його статичний метод values(). Приклад перебору значень Enum:

public enum Level {
    HIGH,
    MEDIUM,
    LOW
}

public class Main {

    public static void main(String[] args) {
        for (Level level : Level.values()) {
            System.out.println(level);
        }
    }
}

Результат виконання цього коду:

HIGH
MEDIUM
LOW

Метод Enum toString()

Кожний Enum за замовчуванням має метод toString() (докладніше Java – метод toString()), котрий повертає рядкове представлення екземпляра Enum. Приклад:

public enum Level {
    HIGH,
    MEDIUM,
    LOW
}

public class Main {

    public static void main(String[] args) {
        Level level = Level.HIGH;
        System.out.println(level.toString()); // HIGH
    }
}

В прикладі вище можна опустити явний виклик методу toString(), так як він викликається автоматично під час друку:

System.out.println(Level.HIGH);

При потребі можна перевизначити метод toString() під власні потреби. Наприклад:

public enum Level {
    HIGH,
    MEDIUM,
    LOW;

    @Override
    public String toString() {
        return "Level: " + this.name();
    }
}

public class Main {

    public static void main(String[] args) {
        Level level = Level.HIGH;
        System.out.println(level); // Level: HIGH
    }
}

Метод Enum valueOf()

Статичний метод valueOf() використовується для отримання екземпляра Еnum за заданим рядковим значенням. Приклад:

public enum Level {
    HIGH,
    MEDIUM,
    LOW
}

public class Main {

    public static void main(String[] args) {
        Level level = Level.valueOf("HIGH");
        System.out.println(level); // HIGH
    }
}

В цьому прикладі змінна level посилається на Level.HIGH, в результаті виконання методу valueOf().

Поля Enum

Є можливість визначати поля всередині Enum Java. В такому разі, кожне значення константа у перечисленні отримує ці поля. Значення для полів потрібно передати в конструктор Enum, під час визначення кожної константи. Приклад:

public enum Level {
    HIGH(3),
    MEDIUM(2),
    LOW(1);

    private final int code;

    private Level(int code) {
        this.code = code;
    }
}

В прикладі вище, конструктор Enum приймає значення типу int, котрим ініціалізує поле code. Саме значення котре передається конструктору, визначено у кожній константі, наприклад:

HIGH(3)

Слід додати, що конструктор Enum у Java повинен бути private. При цьому, якщо модифікатор доступу не вказано явно, він також неявно буде private.

Методи Enum

Також Enum у Java може містити методи. Приклад:

public enum Level {
    HIGH(3),
    MEDIUM(2),
    LOW(1);

    private final int code;

    private Level(int code) {
        this.code = code;
    }

    public int getCode() {
        return this.code;
    }
}

Виклик методу відбувається через посилання на одне з константних значень:

Level level = Level.HIGH;
System.out.println(level.getCode()); // 3

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

Слід додати, якщо поле Enum не оголошено як private, є можливість змінювати значення такого поля через методи (але це не є гарною практикою у випадку роботи з константами).

Абстрактні методи Enum

Окрім звичайних методів, Enum може мати абстрактні методи. Якщо Enum має абстрактний метод, то кожний його екземпляр повинен визначити реалізацію цього методу. Приклад:

public enum Operation {

    ADD {
        @Override
        public int apply(int x, int y) {
            return x + y;
        }
    },
    SUBTRACT {
        @Override
        public int apply(int x, int y) {
            return x - y;
        }
    };

    public abstract int apply(int x, int y);
}

public class Main {

    public static void main(String[] args) {
        Operation operationAdd = Operation.ADD;
        int result = operationAdd.apply(1, 5);
        System.out.println(result); // 6
    }
}

Зверніть увагу на оголошення абстрактного методу apply(int x, int y) в Enum Operation. Кожен екземпляр перечислення (кожна константа) визначає власну реалізацію цього абстрактного методу.

Реалізація інтерфейсу в Enum

Enum у Java можуть реалізовувати інтерфейси. Приклад:

public interface Formatter {
    String format(String input);
}

public enum TextFormat implements Formatter{

    UPPERCASE {
        @Override
        public String format(String input) {
            return input.toUpperCase();
        }
    },
    LOWERCASE {
        @Override
        public String format(String input) {
            return input.toLowerCase();
        }
    }
}

public class Main {

    public static void main(String[] args) {
        TextFormat textFormat = TextFormat.UPPERCASE;
        String message = textFormat.format("hello");
        System.out.println(message); // HELLO
    }
}

Кожний екземпляр Enum повинен визначити реалізацію методів інтерфейсу, котрі не мають реалізації за замовчуванням (Java – default методи в інтерфейсах).

EnumSet

Java має спеціальну реалізацію Set (множини), яка називається EnumSet. Приклад створення екземпляру EnumSet:

public class Main {

    enum Level {
        HIGH,
        MEDIUM,
        LOW
    }

    public static void main(String[] args) {
        EnumSet<Level> enumSet = EnumSet.of(Level.HIGH, Level.MEDIUM);
    }
}

Після створення EnumSet можна використовувати як будь-який інший Set.

EnumMap

Також Java має спеціальну реалізацію Map – а саме EnumMap, котра може використовувати екземпляри Enum в якості ключів. Приклад:

public class Main {

    enum Level {
        HIGH,
        MEDIUM,
        LOW
    }

    public static void main(String[] args) {
        EnumMap<Level, String> levelMessages = new EnumMap<>(Level.class);
        levelMessages.put(Level.HIGH  , "High Level");
        levelMessages.put(Level.MEDIUM, "Medium Level");
        levelMessages.put(Level.LOW   , "Low Level");

        String highMessage = levelMessages.get(Level.HIGH);
        System.out.println(highMessage); // High Level
    }
}

Додаткові особливості Enum у Java

Enum у Java неявно успадковуються від класу java.lang.Enum, тому ваші типи Enum не можуть успадковувати інший клас.

Якщо Enum містить поля та методи, їх визначення завжди повинно бути після списку констант. Крім того, в такому разі перелік констант Enum повинен завершуватись крапкою з комою – ;. Приклад:

public enum Level {
    HIGH(3),
    MEDIUM(2),
    LOW(1);

    private final int code;

    private Level(int code) {
        this.code = code;
    }

    public int getCode() {
        return this.code;
    }
}


Мітки: