1

Тема: Як отримати екземпляр enum за значеннями його полів ?

Є в мене enum :

enum FlipRotate2dEnum {
    NO((byte)0),    None              ((byte)0),
    R2((byte)1),    RotateTwice       ((byte)1),
    FX((byte)2),    FlipX             ((byte)2),
    FY((byte)3),    FlipY             ((byte)3),
    D1((byte)4),    ReflectDiagonal1  ((byte)4),
    D2((byte)5),    ReflectDiagonal2  ((byte)5),
    RC((byte)6),    RotateClockwise   ((byte)6),
    RN((byte)7),    RotateNonClockwise((byte)7);

    public final byte value;
    FlipRotate2dEnum(byte value) { this.value = value; }
}

Я хочу за значенням поля value отримати відповідний екземпляр FlipRotate2dEnum з короткою назвою.
Наприклад, код :

class EnumTest {
    public static void main(String[] args) {
        for(byte i = 0; i < 8; ++i) {
            FlipRotate2dEnum v = FlipRotate2dEnum.valueOf(i);  // або
        //  FlipRotate2dEnum v = (FlipRotate2dEnum)i;          // або ще щось такого типу.
            System.out.println(i + " " + v);
        }
    }
}

має вивести в System.out :

0 NO
1 R2
2 FX
3 FY
4 D1
5 D2
6 RC
7 RN

Для цього, як варіант, можна в FlipRotate2dEnum вставити код :

    static final FlipRotate2dEnum[] UniqueValues = { NO, R2, FX, FY, D1, D2, RC, RN };
    static FlipRotate2dEnum valueOf(byte value) { return UniqueValues[value]; }

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

Чи існує інше (гарніше) рішення ?

2 Востаннє редагувалося koala (13.05.2018 07:06:42)

Re: Як отримати екземпляр enum за значеннями його полів ?

Правильно - це перевизначити (@Override) власний метод toString для enum-а.

Подякували: leofun011

3

Re: Як отримати екземпляр enum за значеннями його полів ?

koala написав:

Правильно - це перевизначити (@Override) власний метод toString для enum-а.

Ви маєте на увазі, додати метод toString() як член enum'а і :
1) лишити все як є ?
чи
2) видалити короткі назви з enum'а ?

Якщо перший варіант, то ОК.
Якщо другий варіант, то короткі назви я змушений залишити, бо користувачі повинні мати можливість витягати екземпляри так :

FlipRotate2dEnum.FX;

4

Re: Як отримати екземпляр enum за значеннями його полів ?

leofun01 написав:
koala написав:

Правильно - це перевизначити (@Override) власний метод toString для enum-а.

Ви маєте на увазі, додати метод toString() як член enum'а і :

і зробити так, щоб вам було зручно. У вас власний метод, робіть у ньому все так, як вам треба.

Подякували: leofun011

5

Re: Як отримати екземпляр enum за значеннями його полів ?

public enum FlipRotate2dEnum {
    None((byte) 0),
    RotateTwice((byte) 1),
    FlipX((byte) 2),
    FlipY((byte) 3),
    ReflectDiagonal1((byte) 4),
    ReflectDiagonal2((byte) 5),
    RotateClockwise((byte) 6),
    RotateNonClockwise((byte) 7);

    public final byte value;

    FlipRotate2dEnum(byte value) {
        this.value = value;
    }

    public static FlipRotate2dEnum from(byte value) {
        for (FlipRotate2dEnum flipRotate : FlipRotate2dEnum.values()) {
            if (flipRotate.value == value) {
                return flipRotate;
            }
        }
        return null;
    }

    public static FlipRotate2dEnum from(int value) {
        return from((byte) value);
    }

    public static void main(String[] args) {
        assert FlipRotate2dEnum.from((byte) 0) == FlipRotate2dEnum.None;
        assert FlipRotate2dEnum.from((byte) 7) == FlipRotate2dEnum.RotateNonClockwise;

        // works too
        assert FlipRotate2dEnum.from(0) == FlipRotate2dEnum.None;
        assert FlipRotate2dEnum.from(7) == FlipRotate2dEnum.RotateNonClockwise;
    }
}

Однак використовувати аліаси в iнамах не варто, тому що хоч семантично FlipRotate2dEnum.None дорівнює FlipRotate2dEnum.NO, в джаві FlipRotate2dEnum.NO == FlipRotate2dEnum.None ~ false. Такий switch теж не спрацює:

final FlipRotate2dEnum none = FlipRotate2dEnum.None;
        switch (none) {
            case N0:
                //
        }
Подякували: leofun01, koala2

6

Re: Як отримати екземпляр enum за значеннями його полів ?

Дійсно, забув, що в Java Enum є reference type.