¿Puedo establecer el valor de inicio de enumeración en Java?

194

Utilizo la enumeración para hacer algunas constantes:

enum ids {OPEN, CLOSE};

el valor ABIERTO es cero, pero lo quiero como 100. ¿Es posible?

qrtt1
fuente
@ScottF ¿Quieres usar enums?
Anish B.
En la respuesta superior, hay una definición de enumeración. Me gustaría un ejemplo de cómo se usaría esa enumeración definida en el código. Por ejemplo, cómo se usaría el ctor definido para crear una instancia de enumeración con un valor entero específico.
ScottF
@ScottF si fuera usted, en lugar de establecer una recompensa por esta publicación, preferiría publicar una pregunta completamente nueva ... o leer la documentación sobre las enumeraciones. Parece que necesita comprender algunos conocimientos básicos al respecto;)
lealceldeiro
enum ids {OPEN = 100, CLOSE};?
Sr. Oscar

Respuestas:

307

Las enumeraciones de Java no son como las enumeraciones de C o C ++, que en realidad son solo etiquetas para enteros.

Las enumeraciones Java se implementan más como clases, e incluso pueden tener múltiples atributos.

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

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

La gran diferencia es que son de tipo seguro, lo que significa que no tiene que preocuparse por asignar una enumeración COLOR a una variable SIZE.

Consulte http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html para obtener más información.

lavinio
fuente
Según su enunciado, la mejor práctica usando java para crear una enumeración de enteros secuenciales (similar a una enumeración de C ++), para un índice en una matriz o algo, sería escribir: enum Ids {NAME (0), AGE (1 ), ALTURA (2), PESO (3); } Gracias, -bn
bn.
Posiblemente, y especialmente si alguna vez serializa los valores integrales en alguna parte.
lavinio
1
¿puedes decir cómo usar esta enumeración en una función?
errores ocurren el
2
Es un vago de los estándares de Java no permitir que se establezca un valor para una enumeración. Al menos c # permite que esto Y sea de tipo seguro.
csmith
2
FWIW, C ++ 11 ahora tiene un tipo seguro enum class.
Phoenix
92

Si. Puede pasar los valores numéricos al constructor para la enumeración, así:

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

  private int value;    

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

  public int getValue() {
    return value;
  }
}

Consulte la Guía del lenguaje Sun Java para obtener más información.

Paul Morie
fuente
Frio. ¿Es posible mezclar? Es decir, solo asigna números a los valores de Enum elegidos.
Frederick Nord el
modificador privado es redundante para constructores de enumeración
Nino van Hooff
@FrederickNord - Claro. Simplemente agregue un segundo constructor privado sin argumentos que se inicialice valuea un (digamos) cero. Luego incluya (digamos) DANCEen la lista de valores.
Stephen C
15

¿Qué hay de usar de esta manera:

public enum HL_COLORS{
          YELLOW,
          ORANGE;

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

solo hay un método ...

puede usar el método estático y pasar la enumeración como parámetro como:

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

Tenga en cuenta que estas dos formas usan menos memoria y más unidades de proceso. No digo que esta sea la mejor manera, pero es solo otro enfoque.

Maher Abuthraa
fuente
1
¿Por qué se getColorValue()sincroniza en el segundo ejemplo?
josaphatv
@josaphatv Toda la funcionalidad en el segundo ejemplo es estática, nunca cambia. Es posible que desee HL_COLORS.getColorValue(HL_COLORS.YELLOW);sin inicializar la enumeración.
mazunki
11

Si usa tipos de enumeración muy grandes, los siguientes pueden ser útiles;

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
fuente
7

Si desea emular una enumeración de C / C ++ (números base y nexts incrementales):

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
ggrandes
fuente
4

La función ordinal () devuelve la posición relativa del identificador en la enumeración. Puede usar esto para obtener una indexación automática con un desplazamiento, como con una enumeración de estilo C.

Ejemplo:

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

Da la salida:

OPEN:  100
CLOSE: 101
OTHER: 102

Editar: acabo de darme cuenta de que esto es muy similar a la respuesta de ggrandes , pero lo dejaré aquí porque está muy limpio y lo más cerca posible de una enumeración de estilo C.

maharvey67
fuente
En el ejemplo, tomas una enumeración y obtienes un int. ¿Puede mostrar el reverso, tomar un int y terminar con una enumeración (sin un caso de cambio explícito para cada valor?)
ScottF
Según la pregunta, creo que esta es la respuesta más adecuada. Aquí hemos cambiado el índice predeterminado de enum para comenzar desde 100 sin definir una nueva variable y asignarla a través del constructor.
Rahul Jain
@RahulJain Prefiero usar la respuesta aceptada. Me parece más limpio.
lealceldeiro
1

@scottf

Una enumeración es como un Singleton. La JVM crea la instancia.

Si lo crearas tú mismo con clases, podría verse así

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


}

Y podría usarse así:

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
fuente
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, probablemente confundiste debido al constructor definido en ENUM.

Déjame explicarte eso.

Cuando class loadercarga la enumclase, el enumconstructor también llama. ¡¡En que!! Sí, se llama OPENy close. Con qué valores 100para OPENy 200paraclose

¿Puedo tener un valor diferente?

Si,

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

Pero, es una mala práctica. enumse usa para representar constantslike days of week, colors in rainbowes decir, un pequeño grupo de constantes predefinidas.

Gibbs
fuente
0

Creo que estás confundido al mirar los enumeradores de C ++. Los enumeradores de Java son diferentes.

Este sería el código si está acostumbrado a enumeraciones de 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
fuente