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?


@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 .


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.


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.


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

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

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.


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

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.


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);
}
};
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.