Saya memiliki enum seperti ini:
public enum PcapLinkType {
DLT_NULL(0)
DLT_EN10MB(1)
DLT_EN3MB(2),
DLT_AX25(3),
/*snip, 200 more enums, not always consecutive.*/
DLT_UNKNOWN(-1);
private final int value;
PcapLinkType(int value) {
this.value= value;
}
}
Sekarang saya mendapatkan int dari input eksternal dan menginginkan input yang cocok - melempar pengecualian jika nilai tidak ada tidak masalah, tetapi sebaiknya saya memilikinya DLT_UNKNOWN
dalam kasus itu.
int val = in.readInt();
PcapLinkType type = ???; /*convert val to a PcapLinkType */
EnumMap
menggunakan enum sebagai kuncinya. Dalam hal ini, OP menginginkan enum sebagai nilai.values()
(jika nilai enum Anda berurutan) atauswitch
pernyataan sederhana akan mengalahkan metode ini dengan mudah . Jika Anda hanya memiliki sedikit entri di dalam Anda,Enum
maka tidak masuk akal untuk menambahkan overhead dari HashMap hanya untuk kenyamanan karena tidak perlu memperbaruiswitch
pernyataan. Cara ini mungkin terlihat lebih elegan, tetapi juga boros.Ada metode statis
values()
yang adalah didokumentasikan, tetapi tidak di mana Anda harapkan itu: http://docs.oracle.com/javase/tutorial/java/javaOO/enum.htmlenum MyEnum { FIRST, SECOND, THIRD; private static MyEnum[] allValues = values(); public static MyEnum fromOrdinal(int n) {return allValues[n];} }
Pada prinsipnya, Anda dapat menggunakan hanya
values()[i]
, tetapi ada rumor yangvalues()
akan membuat salinan larik setiap kali dipanggil.sumber
Anda harus membuat metode statis baru di mana Anda mengulang PcapLinkType.values () dan membandingkan:
public static PcapLinkType forCode(int code) { for (PcapLinkType typе : PcapLinkType.values()) { if (type.getValue() == code) { return type; } } return null; }
Itu akan baik-baik saja jika jarang dipanggil. Jika sering dipanggil, lihat
Map
pengoptimalan yang disarankan oleh orang lain.sumber
Anda dapat melakukan sesuatu seperti ini untuk secara otomatis mendaftarkan semuanya ke dalam koleksi yang kemudian dapat dengan mudah mengonversi bilangan bulat ke enum yang sesuai. (BTW, menambahkannya ke peta di konstruktor enum tidak diperbolehkan . Sangat menyenangkan mempelajari hal-hal baru bahkan setelah bertahun-tahun menggunakan Java. :)
public enum PcapLinkType { DLT_NULL(0), DLT_EN10MB(1), DLT_EN3MB(2), DLT_AX25(3), /*snip, 200 more enums, not always consecutive.*/ DLT_UNKNOWN(-1); private static final Map<Integer, PcapLinkType> typesByValue = new HashMap<Integer, PcapLinkType>(); static { for (PcapLinkType type : PcapLinkType.values()) { typesByValue.put(type.value, type); } } private final int value; private PcapLinkType(int value) { this.value = value; } public static PcapLinkType forValue(int value) { return typesByValue.get(value); } }
sumber
jika Anda memiliki enum seperti ini
public enum PcapLinkType { DLT_NULL(0) DLT_EN10MB(1) DLT_EN3MB(2), DLT_AX25(3), DLT_UNKNOWN(-1); private final int value; PcapLinkType(int value) { this.value= value; } }
maka Anda bisa menggunakannya seperti
PcapLinkType type = PcapLinkType.values()[1]; /*convert val to a PcapLinkType */
sumber
Seperti yang dikatakan @MeBigFatGuy, kecuali Anda dapat membuat
static {...}
blok Anda menggunakan loop di atasvalues()
koleksi:static { for (PcapLinkType type : PcapLinkType.values()) { intToTypeMap.put(type.getValue(), type); } }
sumber
Saya tahu pertanyaan ini berumur beberapa tahun, tetapi karena Java 8, sementara itu, membawa kami
Optional
, saya pikir saya akan menawarkan solusi menggunakannya (Stream
danCollectors
):public enum PcapLinkType { DLT_NULL(0), DLT_EN3MB(2), DLT_AX25(3), /*snip, 200 more enums, not always consecutive.*/ // DLT_UNKNOWN(-1); // <--- NO LONGER NEEDED private final int value; private PcapLinkType(int value) { this.value = value; } private static final Map<Integer, PcapLinkType> map; static { map = Arrays.stream(values()) .collect(Collectors.toMap(e -> e.value, e -> e)); } public static Optional<PcapLinkType> fromInt(int value) { return Optional.ofNullable(map.get(value)); } }
Optional
adalah sepertinull
: ini mewakili kasus ketika tidak ada nilai (valid). Tetapi ini adalah alternatif yang lebih aman untuknull
tipe atau nilai default sepertiDLT_UNKNOWN
karena Anda bisa lupa untuk memeriksa kasusnull
atauDLT_UNKNOWN
. Keduanya adalahPcapLinkType
nilai yang valid ! Sebaliknya, Anda tidak dapat menetapkanOptional<PcapLinkType>
nilai ke variabel tipePcapLinkType
.Optional
membuat Anda memeriksa nilai yang valid terlebih dahulu.Tentu saja, jika Anda ingin mempertahankan
DLT_UNKNOWN
kompatibilitas mundur atau alasan lain apa pun, Anda masih dapat menggunakanOptional
bahkan dalam kasus itu, menggunakanorElse()
untuk menetapkannya sebagai nilai default:public enum PcapLinkType { DLT_NULL(0), DLT_EN3MB(2), DLT_AX25(3), /*snip, 200 more enums, not always consecutive.*/ DLT_UNKNOWN(-1); private final int value; private PcapLinkType(int value) { this.value = value; } private static final Map<Integer, PcapLinkType> map; static { map = Arrays.stream(values()) .collect(Collectors.toMap(e -> e.value, e -> e)); } public static PcapLinkType fromInt(int value) { return Optional.ofNullable(map.get(value)).orElse(DLT_UNKNOWN); } }
sumber
Anda bisa menambahkan metode statis dalam enum Anda yang menerima an
int
sebagai parameter dan mengembalikanPcapLinkType
.public static PcapLinkType of(int linkType) { switch (linkType) { case -1: return DLT_UNKNOWN case 0: return DLT_NULL; //ETC.... default: return null; } }
sumber
switch
pernyataan itu jika Anda menambahkan enum baru. Tidak ideal, IMHO.Ini yang saya gunakan:
public enum Quality {ENOUGH,BETTER,BEST; private static final int amount = EnumSet.allOf(Quality.class).size(); private static Quality[] val = new Quality[amount]; static{ for(Quality q:EnumSet.allOf(Quality.class)){ val[q.ordinal()]=q; } } public static Quality fromInt(int i) { return val[i]; } public Quality next() { return fromInt((ordinal()+1)%amount); } }
sumber
static final PcapLinkType[] values = { DLT_NULL, DLT_EN10MB, DLT_EN3MB, null ...} ... public static PcapLinkType getPcapLinkTypeForInt(int num){ try{ return values[int]; }catch(ArrayIndexOutOfBoundsException e){ return DLT_UKNOWN; } }
sumber
.values()
metode?).--int
, tapi ini jelas salah ketik.null
menggantikanDLT_UKNOWN
:)static final values[] = PcapLinkType.values()
?Tidak ada cara untuk menangani tipe enumerasi berbasis integer dengan elegan. Anda mungkin berpikir untuk menggunakan enumerasi berbasis string daripada solusi Anda. Bukan cara yang disukai sepanjang waktu, tapi masih ada.
public enum Port { /** * The default port for the push server. */ DEFAULT("443"), /** * The alternative port that can be used to bypass firewall checks * made to the default <i>HTTPS</i> port. */ ALTERNATIVE("2197"); private final String portString; Port(final String portString) { this.portString = portString; } /** * Returns the port for given {@link Port} enumeration value. * @return The port of the push server host. */ public Integer toInteger() { return Integer.parseInt(portString); } }
sumber