Bagaimana cara mengubah nilai enum ke int?

240

Saya memiliki fungsi yang mengembalikan tipe int. Namun, saya hanya memiliki nilai enumerasi PAJAK.

Bagaimana saya bisa memasukkan nilai penghitungan pajak ke 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;
}
vrbilgi
sumber
1
Kemungkinan rangkap dari Cara mencocokkan int ke enum
malat

Jawaban:

354

Anda harus membuat enum terbuka value, entah bagaimana

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();
}

(Saya telah mengubah nama menjadi sedikit lebih konvensional dan mudah dibaca, btw.)

Ini dengan asumsi Anda menginginkan nilai yang ditetapkan dalam konstruktor. Jika bukan itu yang Anda inginkan, Anda perlu memberi kami informasi lebih lanjut.

Jon Skeet
sumber
1
@likejiujitsu: Itu berlawanan arah. Dalam pertanyaan ini, OP sudah memiliki nilai tipe Tax, dan ingin mendapatkan nilai numerik darinya.
Jon Skeet
Saya baru saja mencobanya dan menyadari bahwa myEnumValue = MyEnum.valueOf(myInt);arg gagal harus bertipe String - atau ada sesuatu yang saya lewatkan?
likejudo
Solusi ini lebih buruk daripada tidak sama sekali. Sepertinya enum di Jawa tidak seharusnya digunakan? Atau apakah JDK 1.8 telah mengubahnya?
ebyrob
@ebyrob: Mengingat pemungutan suara, sepertinya banyak orang tidak setuju dengan Anda, seperti saya. Jika Anda ingin satu set nilai tetap, enum benar-benar baik-baik saja.
Jon Skeet
209

Saya lebih memilih ini:

public enum Color {

   White,

   Green,

   Blue,

   Purple,

   Orange,

   Red
}

kemudian:

//cast enum to int
int color = Color.Blue.ordinal();
vivia
sumber
34
Ini tidak benar / tidak direkomendasikan oleh Joshua Bloch dalam bukunya Effective Java (2nd ed). Lihat item 31.
user504342
43
@ user504342 Saya tidak memiliki buku edisi ke-2 jadi bisakah Anda memberi kami intisari mengapa buku ini tidak disarankan?
likejudo
17
2 alasan: satu, setiap hubungan antara nilai-nilai ordinal dan konstanta akan pecah jika konstanta baru ditambahkan, dan dua dokumen API secara khusus merekomendasikan untuk tidak melakukannya.
jordanpg
8
Sangat bersih dan sempurna. Saya melihat beberapa "jangan lakukan itu" dan "tidak dianjurkan". Saya harus meneliti mengapa itu dianggap buruk. Beberapa sampel kembung terlihat IMO buruk. Begitu banyak pekerjaan untuk melakukan tugas yang begitu sederhana.
Ramuan Meehan
4
Dalam sebuah tim, Anda cukup yakin bahwa co-developer Anda akan menambah nilai di tengah (lebih buruk di awal), atau hanya mengurutkannya karena mereka tidak ada hubungannya dan benar-benar mengacaukan penggunaan kode.ordinal()
Michael Laffargue
18

Jika Anda ingin nilai yang Anda tetapkan dalam konstruktor, Anda perlu menambahkan metode dalam definisi enum untuk mengembalikan nilai itu.

Jika Anda ingin nomor unik yang mewakili nilai enum, Anda dapat menggunakan ordinal().

unholysampler
sumber
2
Hati-hati. Ada lebih banyak anti-pola perkembangan yang bergantung pada ordinal()kasus penggunaan yang valid untuk ordinal(). Jika Anda perlu menyimpan nilai unik untuk enum, maka simpan saja enum. Ada EnumSets, Daftar Enums, EnumMaps, dan hampir semua koleksi Enum lainnya yang mungkin Anda inginkan tersedia.
Edwin Buck
1
@ EdwinBuck: Itu bagus untuk ditunjukkan, saya hanya ingin menyebutkan keberadaannya ordinal()karena OP tidak memperjelas apa yang dia inginkan.
unholysampler
Jangan sampai ordinal. Silakan periksa enum api tentang ini. Pemungutan suara dihapus.
Hovercraft Full Of Belut
3
Saya ingin tahu apa pendapat orang tentang penggunaan ordinal()internal di dalam enum itu sendiri. Misalnya, saya memiliki enum yang disebut " Season" yang berisi nilai-nilai Spring, Summer, Autumn, dan Winter, dan telah metode umum yang disebut next()yang mengembalikan values()[(ordinal() + 1) % 4] eksternal, ada kode pernah melihat nomor urut, dan tidak akan pernah ada anggota tambahan di enum ini, jadi sepertinya case-use yang valid.
Darrel Hoffman
1
@DarrelHoffman Perasaan saya adalah melakukan hal itu baik-baik saja, karena satu-satunya argumen kuat yang saya lihat menentang penggunaan ordinal()engsel pada kode yang jauh dihancurkan oleh perubahan pada konstanta enum enum. Jika Anda akan memodifikasi konstanta enum, Anda harus sudah berada di file itu. Kebanyakan enum cukup pendek, dan jika tidak, Anda harus memeriksa file dengan lebih teliti. Dalam kedua kasus, Anda mungkin harus memiliki unit test yang mencakup next()metode Anda .
Alan Hensley
12

Kadang-kadang beberapa pendekatan C # membuat hidup lebih mudah di dunia Jawa ..:

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;
Vladi
sumber
Bagi saya ini adalah cara yang paling diinginkan. Saya mendapatkan manfaat dari enum (kejelasan kode), tipe data yang ramah DB, dan saya tidak perlu meneliti 100 alternatif enum untuk melakukannya dengan "cara android". Sederhana dan efektif.
John Ward
Bagus. Seolah-olah java enum benar-benar terputus dari kenyataan dari apa enum digunakan untuk ... terutama jika orang kemudian mulai menyalahgunakannya untuk hal-hal seperti lajang. Pendekatan ini memang memiliki kelemahan itu tidak memiliki cara mudah untuk mendapatkan semua nilai sekalipun.
Nyerguds
Bukankah ini memiliki kelemahan mencoba untuk memberikan nilai enum ke suatu metode? Anda tidak lagi dapat meneruskan XLINK ke suatu metode, karena itu tidak mewakili sesuatu yang konkret. Anda kehilangan pengetikan ke dalam metode Anda. Metode tanda tangan harus dibaca pendek bukan XLINK.
Dustin Jensen
2

Mungkin lebih baik menggunakan representasi String daripada integer, karena String masih valid jika nilai ditambahkan ke enum. Anda dapat menggunakan metode enum's name () untuk mengonversi nilai enum ke String dan metode enum's valueOf () untuk membuat representasi enum dari String lagi. Contoh berikut menunjukkan cara mengubah nilai enum ke String dan kembali (ValueType adalah enum):

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");
Mike
sumber
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.
}
Ieshaan Saxena
sumber
0

Pendekatan yang agak berbeda (setidaknya pada Android) adalah menggunakan anotasi IntDef untuk menggabungkan satu set konstanta int

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

Gunakan sebagai parameter fungsi:

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

atau dalam deklarasi variabel:

@TAX int currentTax = IMPORTEDTAX;
mir
sumber