Czy mogę ustawić wartość początkową enum w Javie?

194

Używam wyliczenia, aby utworzyć kilka stałych:

enum ids {OPEN, CLOSE};

wartość OTWARTA wynosi zero, ale chcę mieć wartość 100. Czy to możliwe?

qrtt1
źródło
@ScottF Czy chcesz używać enum?
Anish B.
W górnej odpowiedzi znajduje się definicja wyliczenia. Chciałbym przykład użycia tego zdefiniowanego wyliczenia w kodzie. Na przykład, w jaki sposób zdefiniowany ctor mógłby zostać użyty do utworzenia wystąpienia enum z określoną wartością całkowitą.
ScottF
@ ScottF, gdybym był tobą, zamiast ustawiać nagrodę za ten post, wolałbym zamieścić zupełnie nowe pytanie ..... lub przeczytać dokumentację dotyczącą wyliczeń. Wygląda na to, że musisz
zdobyć
enum ids {OPEN = 100, CLOSE};?
Pan Oscar

Odpowiedzi:

307

Wyliczenia Java nie są podobne do wyliczeń C lub C ++, które tak naprawdę są po prostu etykietami liczb całkowitych.

Wyliczenia Java są implementowane bardziej jak klasy - i mogą nawet mieć wiele atrybutów.

public enum Ids {
    OPEN(100), CLOSE(200);

    private final int id;
    Ids(int id) { this.id = id; }
    public int getValue() { return id; }
}

Duża różnica polega na tym, że są one bezpieczne dla typu, co oznacza, że ​​nie musisz się martwić przypisaniem wyliczenia KOLORU do zmiennej SIZE.

Więcej informacji można znaleźć na stronie http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html .

lavinio
źródło
Opierając się na twoim oświadczeniu, najlepszą praktyką przy użyciu java do utworzenia wyliczenia liczb całkowitych sekwencyjnych (podobnych do wyliczenia C ++), dla indeksu w tablicy lub czegoś takiego, byłoby napisanie: wyliczanie Ids {NAME (0), AGE (1 ), WYSOKOŚĆ (2), WAGA (3); } Dziękuję, -bn
bn.
Być może, a zwłaszcza jeśli gdzieś szeregujesz wartości całkowite.
lavinio
1
czy możesz powiedzieć, jak używać tego wyliczenia w funkcji?
Błędy występowały
2
Leniwe jest, aby standardy Java nie pozwalały na ustawienie wartości dla wyliczenia. Przynajmniej c # pozwala na to ORAZ jest bezpieczny dla typu.
csmith
2
FWIW, C ++ 11 ma teraz bezpieczny typ enum class.
feniks
92

Tak. Możesz przekazać wartości liczbowe do konstruktora dla wyliczenia, tak jak:

enum Ids {
  OPEN(100),
  CLOSE(200);

  private int value;    

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

  public int getValue() {
    return value;
  }
}

Zobacz Sun Java Język Guide , aby uzyskać więcej informacji.

Paul Morie
źródło
Chłodny. Czy można mieszać? Tj. Przypisuj tylko liczby do wybranych wartości Enum.
Frederick Nord,
prywatny modyfikator jest zbędny dla konstruktorów enum
Nino van Hooff
@FrederickNord - Pewnie. Wystarczy dodać drugi prywatny konstruktor bez argumentów, który inicjuje się valuedo (powiedzmy) zera. Następnie umieść (powiedzmy) DANCEna liście wartości.
Stephen C
15

co z użyciem tego sposobu:

public enum HL_COLORS{
          YELLOW,
          ORANGE;

          public int getColorValue() {
              switch (this) {
            case YELLOW:
                return 0xffffff00;
            case ORANGE:
                return 0xffffa500;    
            default://YELLOW
                return 0xffffff00;
            }
          }
}

jest tylko jedna metoda ...

możesz użyć metody statycznej i przekazać Enum jako parametr taki jak:

public enum HL_COLORS{
          YELLOW,
          ORANGE;

          public static int getColorValue(HL_COLORS hl) {
              switch (hl) {
            case YELLOW:
                return 0xffffff00;
            case ORANGE:
                return 0xffffa500;    
            default://YELLOW
                return 0xffffff00;
            }
          }

Zauważ, że te dwa sposoby zużywają mniej pamięci i więcej jednostek procesowych. Nie twierdzę, że to najlepszy sposób, ale to tylko inne podejście.

Maher Abuthraa
źródło
1
Dlaczego getColorValue()synchronizuje się w drugim przykładzie?
josaphatv
@josaphatv Cała funkcjonalność w drugim przykładzie jest statyczna, nigdy się nie zmienia. Możesz chcieć HL_COLORS.getColorValue(HL_COLORS.YELLOW);bez inicjowania wyliczenia.
mazunki
11

Jeśli używasz bardzo dużych typów wyliczeń, następujące mogą być przydatne;

public enum deneme {

    UPDATE, UPDATE_FAILED;

    private static Map<Integer, deneme> ss = new TreeMap<Integer,deneme>();
    private static final int START_VALUE = 100;
    private int value;

    static {
        for(int i=0;i<values().length;i++)
        {
            values()[i].value = START_VALUE + i;
            ss.put(values()[i].value, values()[i]);
        }
    }

    public static deneme fromInt(int i) {
        return ss.get(i);
    }

    public int value() {
    return value;
    }
}
serdar
źródło
7

Jeśli chcesz emulować wyliczanie C / C ++ (liczba podstawowa i kolejne przyrostowe):

enum ids {
    OPEN, CLOSE;
    //
    private static final int BASE_ORDINAL = 100;
    public int getCode() {
        return ordinal() + BASE_ORDINAL;
    }
};

public class TestEnum {
    public static void main (String... args){
        for (ids i : new ids[] { ids.OPEN, ids.CLOSE }) {
            System.out.println(i.toString() + " " + 
                i.ordinal() + " " + 
                i.getCode());
        }
    }
}
OPEN 0 100
CLOSE 1 101
Grgrandes
źródło
4

Funkcja ordinal () zwraca względną pozycję identyfikatora w wyliczeniu. Możesz użyć tego do uzyskania automatycznego indeksowania z przesunięciem, jak w przypadku wyliczenia typu C.

Przykład:

public class TestEnum {
    enum ids {
        OPEN,
        CLOSE,
        OTHER;

        public final int value = 100 + ordinal();
    };

    public static void main(String arg[]) {
        System.out.println("OPEN:  " + ids.OPEN.value);
        System.out.println("CLOSE: " + ids.CLOSE.value);
        System.out.println("OTHER: " + ids.OTHER.value);
    }
};

Daje wynik:

OPEN:  100
CLOSE: 101
OTHER: 102

Edycja: właśnie zdałem sobie sprawę, że jest to bardzo podobne do odpowiedzi ggrandesa , ale zostawię to tutaj, ponieważ jest bardzo czyste i tak blisko, jak to tylko możliwe, do osiągnięcia wyliczenia w stylu C.

maharvey67
źródło
W tym przykładzie bierzesz wyliczenie i dostajesz int. Czy potrafisz pokazać odwrotność, wziąć int i skończyć enumem (bez wyraźnego przypadku zmiany dla każdej wartości?)
ScottF
Jeśli chodzi o pytanie, uważam, że jest to najbardziej odpowiednia odpowiedź. W tym miejscu zmieniliśmy domyślny indeks wyliczenia, aby zaczynał się od 100 bez definiowania nowej zmiennej i przypisywania jej za pomocą konstruktora.
Rahul Jain
@RahulJain Wolę użyć zaakceptowanej odpowiedzi. Wydaje mi się czystszy.
lealceldeiro
1

@scottf

Wyliczenie jest jak Singleton. JVM tworzy instancję.

Jeśli stworzyłbyś go sam z klasami, mogłoby to wyglądać tak

public static class MyEnum {

    final public static MyEnum ONE;
    final public static MyEnum TWO;

    static {
        ONE = new MyEnum("1");
        TWO = new MyEnum("2");
    }

    final String enumValue;

    private MyEnum(String value){
        enumValue = value;    
    }

    @Override
    public String toString(){
        return enumValue;
    }


}

I może być używany w ten sposób:

public class HelloWorld{

   public static class MyEnum {

       final public static MyEnum ONE;
       final public static MyEnum TWO;

       static {
          ONE = new MyEnum("1");
          TWO = new MyEnum("2");
       }

       final String enumValue;

       private MyEnum(String value){
           enumValue = value;    
       }

       @Override
       public String toString(){
           return enumValue;
       }


   }

    public static void main(String []args){

       System.out.println(MyEnum.ONE);
       System.out.println(MyEnum.TWO);

       System.out.println(MyEnum.ONE == MyEnum.ONE);

       System.out.println("Hello World");
    }
}
sperling
źródło
0
 public class MyClass {
    public static void main(String args[]) {
     Ids id1 = Ids.OPEN;
     System.out.println(id1.getValue());
    }
}

enum Ids {
    OPEN(100), CLOSE(200);

    private final int id;
    Ids(int id) { this.id = id; }
    public int getValue() { return id; }
}

@ scottf, Prawdopodobnie pomyliłeś się z powodu konstruktora zdefiniowanego w ENUM.

Pozwól mi to wyjaśnić.

Gdy class loaderładuje enumklasę, enumwywoływany jest również konstruktor. Na czym !! Tak, jest wywoływany OPENi close. Z jakich wartości 100dla OPENi 200dlaclose

Czy mogę mieć inną wartość?

Tak,

public class MyClass {
    public static void main(String args[]) {
     Ids id1 = Ids.OPEN;
     id1.setValue(2);
     System.out.println(id1.getValue());
    }
}

enum Ids {
    OPEN(100), CLOSE(200);

    private int id;
    Ids(int id) { this.id = id; }
    public int getValue() { return id; }
    public void setValue(int value) { id = value; }
}

Ale to zła praktyka. enumsłuży do reprezentowania constantspodobnych days of week, colors in rainbowtj. takiej małej grupy predefiniowanych stałych.

Gibbs
źródło
0

Myślę, że nie masz pojęcia o modułach wyliczających C ++. Moduł wyliczający Java jest inny.

Byłby to kod, jeśli jesteś przyzwyczajony do wyliczeń C / C ++:

public class TestEnum {
enum ids {
    OPEN,
    CLOSE,
    OTHER;

    public final int value = 100 + ordinal();
};

public static void main(String arg[]) {
    System.out.println("OPEN:  " + ids.OPEN.value);
    System.out.println("CLOSE: " + ids.CLOSE.value);
    System.out.println("OTHER: " + ids.OTHER.value);
}
};
Coristat
źródło