2012-08-06 26 views
49

Tengo el siguiente ejemplo:¿Qué significa realmente EnumSet?

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 la enumeración crea un tipo de enumeración de tamaños.

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

Respuesta

28

Como para cualquier variable, su tipo se encuentra en su declaración:

EnumSet largeSize 

Así que sí, largeSize (que debe ser nombrado largeSizes ya que es una colección) es de tipo EnumSet. También debe tenerse en generified, y por lo tanto ser declarado como

EnumSet<Size> largeSizes 

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

+0

¿Entonces es una especie de Enum dentro de un Enum? significa otro objeto (tamaños grandes) que representa parte de un objeto (Tamaños)? – Adam

+2

No, es un conjunto de valores enum. 'largeSizes' es un conjunto que contiene XL, XXL y XXXL. Podría reemplazarlo con un HashSet, y no cambiaría nada, excepto el rendimiento y el consumo de memoria. 'Size' no es un objeto. Es una clase. Y esta clase define varias constantes: L, XL, XXL, etc. de tipo 'Tamaño'. –

+0

No lo entendí bien ... si el Tamaño (debe ser Tamaños) es un objeto por el que no se ve así: Enum Sizes = new Enum; ? y luego las últimas 3 líneas en el primer código? Si puedo hacer un objeto 'tamaño' de Tamaño, significa que el Tamaño debe ser una Clase ... – Adam

3

Teniendo en cuenta 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); 

así, ¿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.

34

Simplificar el código

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

Se puede ver que largeSize es un conjunto regular, excepto su 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. Esta es la razón por la cual imprime

L XL XXL XXXL 

Si desea saber más detalles le sugiero que lea la fuente de esta clase.

-2

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

public enum Style { BOLD, ITALIC, UNDERLINE, STRIKETHROUGH } 

EnumSet.of(Style.BOLD, Style.ITALIC); 
7

EnumSet se utiliza específicamente para almacenar el elemento tipo enum e iterar sobre él rápidamente. Eg.

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.

3

Según Oracle doc

conjuntos Enum se representan internamente como vectores de bits.Esta representación es extremadamente compacta y eficiente.

Legible, tipo seguro, memoria baja huella ... ¿Qué es lo que quiere más?

23

Un simple Enum es una lista de valores que solo puede seleccionar uno de 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 del Enum, pero esto tiene sus ventajas de legibilidad, mantenimiento más sencillo y estricta verificación de tipos.

Se usará EnumSet cuando necesite una variable para asumir más de un valor Enum al mismo tiempo. Por ejemplo, una fuente con la que escriba en la pantalla puede ser negrita y 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.

comparar los dos:

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

define, cesionarios y luego cheques por un solo valor 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 Enum al mismo tiempo, a continuación, comprueba si uno de ellos es realmente ajustado o no.

3
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 para EnumSet está en orden natural, el orden en que los valores de la enumeración se declararon originalmente.

  • EnumSet class es miembro de Java Collections Framework & no está sincronizado.
  • 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 solo tipo de enumeración .

saber más lee la documentación del API: http://docs.oracle.com/javase/8/docs/api/java/util/EnumSet.html

6

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

El paquete java.util ofrece clases EnumSet para representar eficientemente conjuntos de valores extraídos de un solo tipo de enumeración. Esta clase implementa la interfaz Set, proporcionando toda la riqueza, tipo de seguridad y la interoperabilidad que obtiene con cualquier otra implementación del Conjunto.Pero internamente, cada EnumSet se representa como un vector de bits. Si el tipo de enumeración subyacente tiene sesenta y cuatro elementos o menos, y la mayoría lo hace , todo el EnumSet se representa con una sola longitud, por lo que su rendimiento es comparable al de un campo de bit. Las operaciones masivas, , como removeAll y retainAll, se implementan utilizando bititour aritmética, al igual que lo hará manualmente para los campos de bits. Pero usted está aislado de la fealdad y la propensión a errores del bit manual twiddling. EnumSet hace el trabajo duro por ti.

Así que 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 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 lugar de un Set<Size>EnumSet<Size>. Si bien es bonito obvio y probable que el cliente pase un EnumSet al método, es una buena práctica aceptar una interfaz en lugar de la implementación concreta.

Cuestiones relacionadas