Як перетворити значення enum в int?


240

У мене є функція, яка повертає тип int. Однак у мене є лише значення перерахунку TAX.

Як я можу передати значення перерахування TAX до int?

public enum TAX {
    NOTAX(0),SALESTAX(10),IMPORTEDTAX(5);

    private int value;
    private TAX(int value){
        this.value = value;
    }
}

TAX var = TAX.NOTAX; // This value will differ

public int getTaxValue()
{
  // what do do here?
  // return (int)var;
}

1
Можливий дублікат How to match int to enum
malat

Відповіді:


354

Вам потрібно буде зробити так, щоб перерахунок valueякось розкривався , наприклад

public enum Tax {
    NONE(0), SALES(10), IMPORT(5);

    private final int value;
    private Tax(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }
}

...

public int getTaxValue() {
    Tax tax = Tax.NONE; // Or whatever
    return tax.getValue();
}

(Я змінив імена, щоб бути трохи більш звичайними і читабельними, btw.)

Це припускаючи, що потрібно значення, призначене в конструкторі. Якщо ви цього не хочете, вам потрібно буде надати більше інформації.


1
@likejiujitsu: Це відбувається в зворотному напрямку. У цьому питанні ОП вже має значення типу Tax, і хоче отримати з нього числове значення.
Джон Скіт

Я просто спробував це і зрозумів, що це не вдається, myEnumValue = MyEnum.valueOf(myInt);аргумент має бути типу String - чи щось мені не вистачає?
likejudo

Це рішення гірше нічого. Здається, що перерахунки на Java просто не слід використовувати? Або JDK 1.8 змінив це?
ebyrob

@ebyrob: Враховуючи голосування, схоже, що багато хто з вами не погоджується, як і я. Якщо потрібно фіксований набір значень, перерахунки абсолютно нормальні.
Джон Скіт

209

Я вважаю за краще це:

public enum Color {

   White,

   Green,

   Blue,

   Purple,

   Orange,

   Red
}

тоді:

//cast enum to int
int color = Color.Blue.ordinal();

34
Це невірно / не рекомендується Джошуа Блохом у своїй книзі «Ефективна Java» (2-е видання). Дивіться пункт 31.
user504342

43
@ user504342 У мене немає другого видання книги, тож можете, будь ласка, дати нам суть, чому це не рекомендується?
likejudo

17
2 причини: одна, будь-яка асоціація між порядковими значеннями та константами порушиться, якщо нові константи будуть додані, і два документи API спеціально рекомендують проти цього.
jordanpg

8
Так чисто і ідеально. Я бачу декілька "не робіть цього" і "не рекомендується". Мені доведеться дослідити, чому це вважається поганим. Деякі з роздутих зразків виглядають погано ІМО. Стільки роботи, щоб виконати таке просте завдання.
Герб Механ

4
У команді ви майже впевнені, що ваш співавтор додасть значення в середині (гірше на початку), або просто сортуйте їх, тому що їм нічого не робити і повністю .ordinal()
заплутати

18

Якщо ви хочете, щоб значення, яке ви призначаєте в конструкторі, вам потрібно додати метод у визначенні enum, щоб повернути це значення.

Якщо вам потрібно унікальне число, яке відображає значення перерахунку, ви можете використовувати ordinal().


2
Будь обережний. Існує набагато більше анти-моделей розвитку, на які покладаються, ordinal()ніж на дійсні випадки використання ordinal(). Якщо вам потрібно зберегти унікальне значення для enum, тоді просто збережіть enum. Є EnumSets, Списки Enums, EnumMaps та майже будь-яка інша колекція Enum, яку ви, можливо, захочете.
Едвін Бак

1
@EdwinBuck: Це добре зазначити, я просто хотів згадати про існування, ordinal()оскільки ОП не дало зрозуміти, що він насправді бажає.
unholysampler

Не став порядковим. Будь ласка, перевірте перелік eni щодо цього. Видалення голосів видалено.
Hovercraft Full Of Eels

3
Цікаво, що думки людей щодо використання ordinal()внутрішньо всередині самої ентуми. Наприклад, у мене є перерахування під назвою « Season» , який містить значення Spring, Summer, Autumnі Winter, і це не публічна метод називається next()повертає values()[(ordinal() + 1) % 4] Зовнішньо, що не код коли - небудь побачить порядковий номер, і ніколи не будуть додаткові членами в цьому переліку, тому це здається дійсним випадком використання.
Даррель Гофман

1
@DarrelHoffman Моє відчуття полягає в тому, що робити це добре, оскільки єдині сильні аргументи, які я бачу, проти використання ordinal()шарніра на далекому коді, порушеному змінами констант перерахування перерахунків. Якщо ви збираєтеся змінювати константи enum, вам доведеться вже бути у цьому файлі. Більшість перерахунків досить короткі, і якщо це не так, то все одно слід ретельно перевірити файл. В обох випадках ви, ймовірно, повинні пройти одиничний тест, що охоплює ваш next()метод.
Алан Хенслі

12

Іноді деякий підхід C # полегшує життя у світі Java ..:

class XLINK {
static final short PAYLOAD = 102, ACK = 103, PAYLOAD_AND_ACK = 104;
}
//Now is trivial to use it like a C# enum:
int rcv = XLINK.ACK;

Для мене це найбільш бажаний шлях. Я отримую переваги enum (чіткість коду), тип даних, що відповідає БД, і мені не доведеться досліджувати 100 альтернатив перерахунку, щоб зробити це "андроїдним шляхом". Простий і ефективний.
Джон Уорд

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

Чи не має цього недоліку намагатися передати значення перерахунку методу? Ви більше не можете передавати XLINK методу, оскільки він не представляє нічого конкретного. Ви втрачаєте введення свого методу. Підпис методу повинен був би читати короткий замість XLINK.
Дастін Йенсен

2

Можливо, краще використовувати представлення String, ніж ціле число, тому що String все ще діє, якщо значення додаються до enum. Ви можете використовувати метод name () enum () для перетворення значення enum в метод String an enum's valueOf (), щоб знову створити представлення enum з String. Наступний приклад показує, як перетворити значення enum в String і назад (ValueType - це перерахунок):

ValueType expected = ValueType.FLOAT;
String value = expected.name();

System.out.println("Name value: " + value);

ValueType actual = ValueType.valueOf(value);

if(expected.equals(actual)) System.out.println("Values are equal");

1
public enum Tax {

NONE(1), SALES(2), IMPORT(3);

private final int value;
    private Tax(int value) {
        this.value = value;
    }

    public String toString() {
        return Integer.toString(value);
    }
}

class Test {
    System.out.println(Tax.NONE);    //Just an example.
}

0

Дещо інший підхід (принаймні на Android) полягає у використанні анотації IntDef для поєднання набору констант int

@IntDef({NOTAX, SALESTAX, IMPORTEDTAX})
@interface TAX {}
int NOTAX = 0;
int SALESTAX = 10;
int IMPORTEDTAX = 5;

Використовувати як функціональний параметр:

void computeTax(@TAX int taxPercentage){...} 

або у змінній декларації:

@TAX int currentTax = IMPORTEDTAX;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.