recorrer que programacion obtener herencia estados enum ejemplo java enums enumset

que - Implementando un bitfield usando Java enums



que es un enum en java (5)

Mantengo un gran archivo de documentos y a menudo uso campos de bits para registrar el estado de mis documentos durante el proceso o al validarlos. Mi código heredado simplemente usa constantes int estáticas tales como:

static int DOCUMENT_STATUS_NO_STATE = 0 static int DOCUMENT_STATUS_OK = 1 static int DOCUMENT_STATUS_NO_TIF_FILE = 2 static int DOCUMENT_STATUS_NO_PDF_FILE = 4

Esto hace que sea bastante fácil indicar el estado en que se encuentra un documento, configurando los indicadores apropiados. Por ejemplo:

status = DOCUMENT_STATUS_NO_TIF_FILE | DOCUMENT_STATUS_NO_PDF_FILE;

Como el enfoque de usar constantes estáticas es una mala práctica y porque me gustaría mejorar el código, estaba buscando usar Enums para lograr lo mismo. Hay algunos requisitos, uno de ellos es la necesidad de guardar el estado en una base de datos como un tipo numérico. Entonces, hay una necesidad de transformar las constantes de enumeración en un valor numérico. A continuación se muestra mi primer enfoque y me pregunto si esta es la forma correcta de hacerlo.

class DocumentStatus{ public enum StatusFlag { DOCUMENT_STATUS_NOT_DEFINED(1<<0), DOCUMENT_STATUS_OK(1<<1), DOCUMENT_STATUS_MISSING_TID_DIR(1<<2), DOCUMENT_STATUS_MISSING_TIF_FILE(1<<3), DOCUMENT_STATUS_MISSING_PDF_FILE(1<<4), DOCUMENT_STATUS_MISSING_OCR_FILE(1<<5), DOCUMENT_STATUS_PAGE_COUNT_TIF(1<<6), DOCUMENT_STATUS_PAGE_COUNT_PDF(1<<7), DOCUMENT_STATUS_UNAVAILABLE(1<<8); private final long statusFlagValue; StatusFlag(long statusFlagValue) { this.statusFlagValue = statusFlagValue; } public long getStatusFlagValue(){ return statusFlagValue; } } /** * Translates a numeric status code into a Set of StatusFlag enums * @param numeric statusValue * @return EnumSet representing a documents status */ public EnumSet<StatusFlag> getStatusFlags(long statusValue) { EnumSet statusFlags = EnumSet.noneOf(StatusFlag.class); StatusFlag.each { statusFlag -> long flagValue = statusFlag.statusFlagValue if ( (flagValue&statusValue ) == flagValue ) { statusFlags.add(statusFlag); } } return statusFlags; } /** * Translates a set of StatusFlag enums into a numeric status code * @param Set if statusFlags * @return numeric representation of the document status */ public long getStatusValue(Set<StatusFlag> flags) { long value=0; flags.each { statusFlag -> value|=statusFlag.getStatusFlagValue() } return value; } public static void main(String[] args) { DocumentStatus ds = new DocumentStatus(); Set statusFlags = EnumSet.of( StatusFlag.DOCUMENT_STATUS_OK, StatusFlag.DOCUMENT_STATUS_UNAVAILABLE); assert ds.getStatusValue( statusFlags )==258 // 0000.0001|0000.0010 long numericStatusCode = 56; statusFlags = ds.getStatusFlags(numericStatusCode); assert !statusFlags.contains(StatusFlag.DOCUMENT_STATUS_OK); assert statusFlags.contains(StatusFlag.DOCUMENT_STATUS_MISSING_TIF_FILE); assert statusFlags.contains(StatusFlag.DOCUMENT_STATUS_MISSING_PDF_FILE); assert statusFlags.contains(StatusFlag.DOCUMENT_STATUS_MISSING_OCR_FILE); } }


En lugar de definir parámetros de constructor, simplemente podría usar el valor ordinal() interno para calcular esto.

public enum StatusFlag { DOCUMENT_STATUS_NOT_DEFINED, DOCUMENT_STATUS_OK, DOCUMENT_STATUS_MISSING_TID_DIR, DOCUMENT_STATUS_MISSING_TIF_FILE, DOCUMENT_STATUS_MISSING_PDF_FILE, DOCUMENT_STATUS_MISSING_OCR_FILE, DOCUMENT_STATUS_PAGE_COUNT_TIF, DOCUMENT_STATUS_PAGE_COUNT_PDF, DOCUMENT_STATUS_UNAVAILABLE; public long getStatusFlagValue(){ return 1 << this.ordinal(); } }

Tenga en cuenta que ahora debe abstenerse de reordenar, insertar (que no sea el final) o eliminar entradas; de lo contrario, los valores de los indicadores cambiarán y el contenido de la base de datos cambiará.


He creado una biblioteca completa para este problema: http://claude-martin.ch/enumbitset/

El objetivo principal era almacenar conjuntos de tipos enum en bitfields. Pero también es compatible con otros tipos.

Con esto no necesitaría ningún método adicional como su "getStatusFlags ()". Se puede usar en cualquier tipo de enumeración existente simplemente agregando la interfaz EnumBitSetHelper (se usa como un "rasgo"). Cada constante enum puede crear un "EnumBitSet" que tiene todos los métodos de EnumSet y BitSet de Java. Entonces puede trabajar con estos conjuntos de constantes enum y convertirlos en valores bitfield.

Es compatible con muchos formatos, como BigInteger y largo para almacenar fácilmente el valor en un campo de bits. Pero tenga en cuenta que esto solo funciona con Java versión 8 y más reciente.


No le des valores a tus enums. Use un EnumSet para combinarlos, y use Enum.ordinal() cuando persista para convertir a / desde un solo entero. También puede encontrar Class.getEnumConstants() útil al reconstruir el conjunto a partir del número entero.


Una forma ligeramente mejor sería almacenar el resultado de 1 << this.ordinal() en un campo cuando se construyen los valores enum. De esta manera, no tiene que proporcionar cada valor manualmente, y la bandera solo se calcula una vez.

public enum StatusFlag { DOCUMENT_STATUS_NOT_DEFINED, DOCUMENT_STATUS_OK, DOCUMENT_STATUS_MISSING_TID_DIR, DOCUMENT_STATUS_MISSING_TIF_FILE, DOCUMENT_STATUS_MISSING_PDF_FILE, DOCUMENT_STATUS_MISSING_OCR_FILE, DOCUMENT_STATUS_PAGE_COUNT_TIF, DOCUMENT_STATUS_PAGE_COUNT_PDF, DOCUMENT_STATUS_UNAVAILABLE; public final int flag; StatusFlag() { this.flag = 1 << this.ordinal(); } }

EDITAR: también podría ser útil tener el método isFlagSet.


su enfoque es exactamente la manera de hacerlo.