Java'da bir numaram var:
public enum Months
{
JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC
}
Enum değerlerine dizine göre erişmek istiyorum, ör.
Months(1) = JAN;
Months(2) = FEB;
...
Bunu nasıl yapacağım?
Java'da bir numaram var:
public enum Months
{
JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC
}
Enum değerlerine dizine göre erişmek istiyorum, ör.
Months(1) = JAN;
Months(2) = FEB;
...
Bunu nasıl yapacağım?
Month
yerleşik bir enum ile birlikte gelir .
Yanıtlar:
Bunu dene
Months.values()[index]
public static final ArrayList<Months> ALL = new ArrayList<Month>() {{ for (Months m : Months.values()) add(m); }};
Months i = ALL.get(index)
İşte bunu yapmanın üç yolu.
public enum Months {
JAN(1), FEB(2), MAR(3), APR(4), MAY(5), JUN(6), JUL(7), AUG(8), SEP(9), OCT(10), NOV(11), DEC(12);
int monthOrdinal = 0;
Months(int ord) {
this.monthOrdinal = ord;
}
public static Months byOrdinal2ndWay(int ord) {
return Months.values()[ord-1]; // less safe
}
public static Months byOrdinal(int ord) {
for (Months m : Months.values()) {
if (m.monthOrdinal == ord) {
return m;
}
}
return null;
}
public static Months[] MONTHS_INDEXED = new Months[] { null, JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC };
}
import static junit.framework.Assert.assertEquals;
import org.junit.Test;
public class MonthsTest {
@Test
public void test_indexed_access() {
assertEquals(Months.MONTHS_INDEXED[1], Months.JAN);
assertEquals(Months.MONTHS_INDEXED[2], Months.FEB);
assertEquals(Months.byOrdinal(1), Months.JAN);
assertEquals(Months.byOrdinal(2), Months.FEB);
assertEquals(Months.byOrdinal2ndWay(1), Months.JAN);
assertEquals(Months.byOrdinal2ndWay(2), Months.FEB);
}
}
public static
değiştirilebilir (hem dizi hem de olmayan final
). Euw. Ve bir bombayı IllegalArgumentException
geri vermekten çok daha mantıklı null
.
Ben de aynısını denedim ve aşağıdaki çözümü buldum:
public enum Countries {
TEXAS,
FLORIDA,
OKLAHOMA,
KENTUCKY;
private static Countries[] list = Countries.values();
public static Countries getCountry(int i) {
return list[i];
}
public static int listGetLastIndex() {
return list.length - 1;
}
}
Sınıfın bir dizi içinde kaydedilmiş kendi değerleri vardır ve diziyi indeks pozisyonundaki numaralandırmak için kullanırım. Yukarıda bahsedildiği gibi diziler 0'dan sayılmaya başlar, dizininizin '1'den başlamasını istiyorsanız bu iki yöntemi şu şekilde değiştirmeniz yeterlidir:
public static String getCountry(int i) {
return list[(i - 1)];
}
public static int listGetLastIndex() {
return list.length;
}
Ana sayfamın içinde gerekli ülkeleri alıyorum.
public static void main(String[] args) {
int i = Countries.listGetLastIndex();
Countries currCountry = Countries.getCountry(i);
}
currCountry'yi son ülke, bu durumda Ülkeler.KENTUCKY olarak ayarlar.
Nesnelerinizi almak için sabit kodlanmış belirteçler kullanıyorsanız, bu kodun ArrayOutOfBoundsExceptions'dan çok etkilendiğini unutmayın.
Geçenlerde aynı sorunu yaşadım ve Harry Joy'un sağladığı çözümü kullandım. Bu çözüm yalnızca sıfır tabanlı numaralandırma ile çalışır. Ayrıca, aralık dışı dizinler ile ilgilenmediği için tasarruf etmeyi de düşünmem.
Kullanmaya son verdiğim çözüm o kadar basit olmayabilir, ancak tamamen kurtarıcıdır ve büyük numaralandırmalarla bile kodunuzun performansına zarar vermez:
public enum Example {
UNKNOWN(0, "unknown"), ENUM1(1, "enum1"), ENUM2(2, "enum2"), ENUM3(3, "enum3");
private static HashMap<Integer, Example> enumById = new HashMap<>();
static {
Arrays.stream(values()).forEach(e -> enumById.put(e.getId(), e));
}
public static Example getById(int id) {
return enumById.getOrDefault(id, UNKNOWN);
}
private int id;
private String description;
private Example(int id, String description) {
this.id = id;
this.description= description;
}
public String getDescription() {
return description;
}
public int getId() {
return id;
}
}
Endeksinizle asla menzil dışına çıkmayacağınızdan eminseniz ve UNKNOWN
yukarıda yaptığım gibi kullanmak istemiyorsanız , elbette şunları da yapabilirsiniz:
public static Example getById(int id) {
return enumById.get(id);
}