Java의 인덱스에서 Enum 값을 얻는 방법은 무엇입니까?


96

Java에 열거 형이 있습니다.

public enum Months
{
    JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC
}

인덱스로 열거 형 값에 액세스하고 싶습니다.

Months(1) = JAN;
Months(2) = FEB;
...

어떻게해야합니까?


12
컴퓨터 과학에서, 지수가 1이 아닌 ;-), 0에서 시작
fredoverflow

1
정말 하시겠습니까? 일반적으로 저수준 데이터 구조를 구현하는 것 외에는 서수를 건드리지 않아야합니다 (그런 다음 지속성을 위해 이름과 같은 대체 메커니즘을 사용하십시오).
톰 Hawtin의 - tackline

java.util.Calendar 클래스의 상수도 사용할 수 있습니다. 1 월부터 12 월까지는 0-11로 번호가 매겨집니다. 12 월은 12 월 (음력과 관련이 있음)이므로주의하십시오. 하지만 JRE에서 이미 "주식"이되는 월 상수를 다시 발명하는 이유가 궁금합니다.
Chris Aldrich

2FredOverflow : Aggree, 잘못된 인덱싱을 사용했습니다. 2Tom Hawtin : 예, 확실합니다. 일부 프레임 워크로 데이터를 유지하고 열거 형이 아닌 정수 인덱스를 반환합니다. 2Chris Aldrich : 이것은 실제 사례와 일치하지 않는 더미 예제입니다.
jk_

그건 그렇고, Java 8 이상에는 Monthenum이 내장되어 있습니다.
Basil Bourque

답변:


229

이 시도

Months.values()[index]

37
매번 값 배열의 복사본을 복제하므로 성능에 민감한 코드의 내부 루프에서 이것을 호출하는 경우 정적 복사본을 만들고 사용할 수 있습니다.
Christopher Barber

1
혼란스럽고 왜 대신 배열을 사용하지 않겠습니까?
Anudeep Samaiya 2015 년

@AnudeepSamaiya는 모든 곳에서 months [1] 대신 코드에서 적절한 열거 형 상수 (Months.JAN)를 사용하고 싶을 수 있습니다.
해리 기쁨

: @Christopher 이발사는 여기에 "정적 복사본을 만드는"에 대한 한 줄의 public static final ArrayList<Months> ALL = new ArrayList<Month>() {{ for (Months m : Months.values()) add(m); }};다음으로 요소에 액세스 할 수 있습니다Months i = ALL.get(index)
muelleth

. 클론 (() 단순히 Months.values를 사용하는 것이 더 쉽습니다) 또는 불변의리스트에 포장하는 가변성에 대한 편집증 경우 (컬렉션 참조) 것
크리스토퍼 이발사

20

이를 수행하는 세 가지 방법이 있습니다.

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

}

5
public static변경 가능 (배열 및 비 모두 final). 유우. 그리고 IllegalArgumentExceptiona는 null폭탄을 반환하는 것보다 훨씬 더 의미가 있습니다.
Tom Hawtin-tackline

2

나는 똑같이 시도하고 다음과 같은 해결책을 찾았습니다.

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

클래스에는 배열 내부에 저장된 자체 값이 있으며 배열을 사용하여 indexposition에서 열거 형을 가져옵니다. 위에서 언급했듯이 배열은 0부터 계산하기 시작합니다. 인덱스가 '1'부터 시작되도록하려면이 두 가지 방법을 다음과 같이 변경하면됩니다.

public static String getCountry(int i) {
    return list[(i - 1)];
}

public static int listGetLastIndex() {
    return list.length;
}

내 메인 내부에서 필요한 국가 개체를 얻습니다.

public static void main(String[] args) {
   int i = Countries.listGetLastIndex();
   Countries currCountry = Countries.getCountry(i);
}

currCountry를 마지막 국가로 설정합니다 (이 경우에는 countries.KENTUCKY).

개체를 가져 오기 위해 하드 코딩 된 인덱스를 사용하는 경우이 코드는 ArrayOutOfBoundsExceptions의 영향을 많이받습니다.


1

나는 최근에 같은 문제가 있었고 Harry Joy가 제공 한 솔루션을 사용했습니다. 이 솔루션은 0 기반 enumaration에서만 작동합니다. 또한 범위를 벗어난 인덱스를 처리하지 않기 때문에 저장이라고 생각하지 않습니다.

내가 사용한 솔루션은 그렇게 간단하지는 않지만 완전히 저장되며 큰 열거 형으로도 코드의 성능을 손상시키지 않습니다.

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

인덱스 범위를 벗어나지 않을 것이라고 확신하고 UNKNOWN위에서했던 것처럼 사용하고 싶지 않다면 물론 다음을 수행 할 수 있습니다.

public static Example getById(int id) {
        return enumById.get(id);
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.