2010-07-29 20 views
6

¿Es posible definir algo como esto en java?¿Número para cada artículo enumerado?

código C#:

public enum Character 
{ 
    A = 1, 

    B = 2, 

    C = 4, 

    D = 8 

} 


... 

Character ch = /* from user */ 

if(ch & Character.A) 
{ 
    // some operation... 
} 

por ejemplo, si ch conjunto a continuación Character.B resultado de if será false:

ch = 00000000 00000000 00000000 00000010 
A = 00000000 00000000 00000000 00000001 
------------------------------------------ 
& 00000000 00000000 00000000 00000000 

que desea implementar algo así! ¿Es posible alguna vez en Java?

Respuesta

17

Bueno, se puede casi hace eso:

public enum CharEnum // Let's avoid java.lang.* clashes 
{ 
    A(1), B(2), C(4), D(8); 

    private final int mask; 

    private CharEnum(int mask) 
    { 
     this.mask = mask; 
    } 

    public int getMask() 
    { 
     return mask; 
    } 
} 

continuación:

CharEnum ch = /* from user */ 

if ((ch.getMask() & CharEnum.A.getMask()) > 0) 
{ 
    // some operation... 
} 

Esto puede ser útil en algunas situaciones, pero como dijo Michael definitivamente debe mirar a EnumSet para uso general Opciones de "conjunto de valores".

Si haces decide ir a por una enumeración con valores, se puede poner la lógica adicional dentro de la enumeración en sí:

public enum CharEnum 
{ 
    // Other code as before 

    public boolean overlapsWith(CharEnum ch) 
    { 
     return (ch.mask & mask) > 0; 
    } 
} 
+0

Debe agregar algunos paréntesis allí: 'if ((ch.getMask() & CharEnum.A.getMask())> 0)' –

+0

@True Soft: Reparado, gracias. –

4

(Por supuesto, la elección de Character como el nombre de su enumeración es muy confuso, ya que crea un conflicto con java.lang.Character que se importa automáticamente en cada unidad de compilación)

Usted puede utilizar el método ordinal() para obtener el entero asociado con una constante enum. De todos modos, tengo la sensación de que lo que estás tratando de lograr se puede realizar mediante métodos definidos enum. Quiero decir, la enumeración de Java es más poderosa que la de C/C++ porque puedes asociar el comportamiento con ellas.

public enum Chr { 
    A { 
     @Override public void doSomething(int c) { 
     // some operation ... 
     } 
    }, 
    B, 
    C, 
    D; 

    public void doSomething(int c) { 
     // some default behavior 
    } 
    } 

A raíz de su comentario:

Puede definir un campo que llevará a cabo este valor, y tienen el constructor inicializa, de la siguiente manera:

public enum Chr { 
    A(1), 
    B(2), 
    C(4), 
    D(8) 
    ; 

    public Chr(int n) { value = n; }   
    public final int value; 
    } 



    Character ch = ... // from user 
    if(ch & Chr.A.value) { 
    ... 
    } 
2

que podría hacer algo así como que el uso Enum.ordinal(), pero sería un diseño realmente malo. Debe usar == para comparaciones de igualdad y EnumSet para operaciones de conjunto.

1

Estoy de acuerdo con Itay, y para conseguir un poco más lejos Voy a recomendar la lectura de Effective Java Second Edition tiene un capítulo completo realmente interesante sobre las enumeraciones de Java.

1

Estoy de acuerdo con Michael Borgwardt y Jon Skeet que vale la pena mirar un EnumSet. Hubiera elegido EnumSet en operaciones bit a bit como las que tiene, por lo que demostraré cómo usar EnumSet.

 

Parece que tu Character enumeración (vamos a llamarlo CharEnum de ahora en adelante) CharEnum está siendo utilizado como un campo de bits, donde cada enumeración tiene un valor entero con juego de un solo bit:

A = 00000000 00000000 00000000 00000001 
B = 00000000 00000000 00000000 00000010 
C = 00000000 00000000 00000000 00000100 
D = 00000000 00000000 00000000 00001000 

Esto es muy similar a lo que hace un EnumSet; tiene un vector de bits interno que asigna automáticamente cada enumeración a un bit en un long. A medida que el Javadoc de que dice, "El rendimiento de espacio y tiempo de esta clase debe ser lo suficientemente bueno como para permitir su uso como una alta calidad, typesafe alternativa a los tradicionales basados ​​en int 'indicadores de bits.'

es una continuación ejemplo de cómo usarlo

public enum CharEnum { 
    A, B, C, D; 
} 

y luego

EnumSet<CharEnum> ch = /* from user */ 

if (ch.contains(CharEnum.A)) { 
    // some operation... 
} 

No hay necesidad de especificar los bits en cualquier lugar, por lo que es mucho más simple código!

Una advertencia: esto solo funciona porque los valores enumerados en su ejemplo de C# tienen solo un bit establecido cada uno. Si usted tenía un valor de enumeración como esto:

E = 00011000 01110111 11100101 10000101 

a continuación, un EnumSet no sería apropiado. En ese caso, debería ver una de las otras respuestas aquí.

Cuestiones relacionadas