utils sets retainall remove metodos linkedset java object enums enumset

java - sets - ¿Qué significa realmente EnumSet?



set retainall java (9)

Convierte rápidamente cualquier elemento Enum en un conjunto, EnumSet es otro tipo de conjunto.

public enum Style { BOLD, ITALIC, UNDERLINE, STRIKETHROUGH } EnumSet.of(Style.BOLD, Style.ITALIC);

Tengo el siguiente ejemplo:

import java.util.EnumSet; import java.util.Iterator; public class SizeSet { public static void main(String[] args) { EnumSet largeSize = EnumSet.of(Size.XL,Size.XXL,Size.XXXL); for(Iterator it = largeSize.iterator();it.hasNext();){ Size size = (Size)it.next(); System.out.println(size); } } } enum Size { S, M, L, XL, XXL, XXXL; }

En este código, puedo entender que Enum crea un tipo de Tamaños Enum.

Mi pregunta es: ¿ largeSize es un objeto del tipo EnumSet? que significa realmente? Realmente quiero entenderlo mejor.


Dado el siguiente ejemplo:

.... public static final String S = "s"; public static final String M = "m"; public static final String L = "l"; .... Set<String> sizeSet = new HashSet<String>(); sizeSet.add(S); sizeSet.add(M);

Entonces, ¿qué es sizeSet ​​en el ejemplo anterior?

EnumSet no es nada diferente del ejemplo anterior, solo que EnumSet es una implementación de conjunto especial que funciona con y optimizada con tipos enum, eso es todo.


De acuerdo con el API

Los conjuntos Enum están representados internamente como vectores de bits. Esta representación es extremadamente compacta y eficiente.

Legible, tipo seguro, bajo consumo de memoria ... ¿Qué es lo que más quieres?


Del propio libro de Joshua Bloch y en su propia palabra:

El paquete java.util proporciona la clase EnumSet para representar de manera eficiente conjuntos de valores tomados de un único tipo de enumeración. Esta clase implementa la interfaz Set, brindando toda la riqueza, tipo de seguridad e interoperabilidad que obtienes con cualquier otra implementación de Set. Pero internamente, cada EnumSet se representa como un vector de bits. Si el tipo de enumeración subyacente tiene sesenta y cuatro o menos elementos, y la mayoría lo hace, todo el EnumSet se representa con una única longitud, por lo que su rendimiento es comparable al de un campo de bit. Las operaciones masivas, como removeAll y retainAll, se implementan utilizando aritmética de bits, al igual que lo hará manualmente para los campos de bits. Pero está aislado de la fealdad y la propensión a los errores de los movimientos manuales de bits. EnumSet hace el trabajo duro por ti.

Entonces podemos hacer algo como esto.

public class SizeSet { public enum Size {S, M, L, XL, XXL, XXXL} public void applySize(Set<Size> sizes){} }

Código de cliente llamando podría hacer algo como

SizeSet largeSizeSet = new SizeSet(); largeSizeSet.applySize(EnumSet.of(Size.L, Size.XXL, Size.XXL));

Tenga en cuenta que el método applySize toma el Set<Size> lugar de un EnumSet<Size> . Si bien es bastante obvio y es probable que el cliente transfiera un EnumSet al método, es una buena práctica aceptar una interfaz en lugar de la implementación concreta.


En cuanto a cualquier variable, su tipo se encuentra en su declaración:

EnumSet largeSize

Así que sí, largeSize (que debería llamarse largeSizes ya que es una colección) es de tipo EnumSet . También debe ser generizado, y así ser declarado como

EnumSet<Size> largeSizes

Lo que significa, es que largeSizes es de tipo EnumSet . Un EnumSet es un Set que contiene una instancia enum de un tipo de enumeración específico, de una manera más eficiente que otras implementaciones de Set (como HashSet , TreeSet , etc.). Para saber qué es un EnumSet , lea su API .


EnumSet se usa específicamente para almacenar el elemento tipo enum y repetirlo rápidamente. P.ej.

for (Day d : EnumSet.range(Day.MONDAY, Day.FRIDAY)) System.out.println(d);

El fragmento de arriba mostrará los días de la semana de lunes a viernes.


Simplificando tu código

EnumSet<Size> largeSize = EnumSet.of(Size.XXXL, Size.XXL, Size.XL, Size.L); for(Size size: largeSize) System.out.print(size+" ");

Puede ver que largeSize es un conjunto regular, excepto que está diseñado para almacenar enumeraciones. ¿Cómo es eso diferente? En primer lugar, la JVM conoce todos los valores posibles del conjunto, lo que significa que en lugar de almacenar todos los objetos, puede usar un mapa de bits donde 1 significa que el elemento está presente y 0 significa que no lo está. Esto también significa que el orden del conjunto es el orden de los valores ordinales, es decir, el orden en que se definieron. Por eso esta impresión

L XL XXL XXXL

Si quieres saber más detalles, te sugiero que leas la fuente de esta clase.


Un Enum simple es una lista de valores de la que solo puede seleccionar uno a la vez. Usando su ejemplo, un tamaño puede ser solo uno de S, M, L, etc. para cualquier tela dada. Puede usar constantes simples en lugar de Enum pero esto tiene sus ventajas de legibilidad, mantenimiento más fácil y estricta verificación de tipos.

Un EnumSet se usará cuando tenga la necesidad de que una variable asuma más de un valor de Enum al mismo tiempo. Por ejemplo, una fuente con la que escriba en la pantalla puede ser tanto negrita como cursiva al mismo tiempo. Un EnumSet le permitirá agregar los diversos valores y probar si alguno de ellos está realmente configurado en un momento dado. Si ha venido a Java desde otros lenguajes de programación, esta es la funcionalidad generalmente llamada flags .

Compara los dos:

enum Size { S, M, L, XL, XXL, XXXL } Size currentSize; ... currentSize = Size.S; ... if (currentSize == Size.S) ...

define, asigna y luego verifica un solo valor de Enum .

enum FontStyle { Bold, Italic, Underline, Strikethrough } EnumSet<FontStyle> currentStyle; ... currentStyle = EnumSet.of(FontStyle.Bold, FontStyle.Italic); ... if (currentStyle.contains(FontStyle.Italic)) ...

define, asigna dos valores de Enum al mismo tiempo, luego verifica si uno de ellos está realmente configurado o no.


EnumSet largeSize

EnumSet largeSize es un conjunto de valores Enum que contiene XL, XXL y XXXL.

Size

El tamaño es una clase de tipo Enum con valores constantes S, M, L, XL, XXL, XXXL.

largeSize.iterator()

El iterador de EnumSet está en orden natural, el orden en el que se declararon originalmente los valores de la enumeración.

  • La clase EnumSet es miembro de Java Collections Framework y no está sincronizada.
  • Es una implementación de conjunto de alto rendimiento, son mucho más rápidos que HashSet.
  • Todos los elementos de cada instancia de EnumSet deben ser elementos de un único tipo de enumeración.

Para saber más, lee el documento de la API: http://docs.oracle.com/javase/8/docs/api/java/util/EnumSet.html