2012-05-08 20 views
13

Estoy escribiendo un programa con muchas enumeraciones, y tengo que devolver mucho el conjunto de claves de un EnumMap. Pero EnumMap.keySet() devuelve una Set(), por lo que con el fin de obtener la EnumSet que quiero, tengo que usar un yeso:¿Por qué EnumMap <T> .keySet() devuelve un conjunto <T>() y no un EnumSet <T>()?

EnumMap<SomeEnum, Object> myMap = getMap(); 
EnumSet<SomeEnum> myEnum = (EnumSet<SomeEnum>) myMap.keySet(); 

Si no emitidos, el compilador se quejará de una coincidencia de tipos; no puede convertir de Set<SomeEnum> a EnumSet<SomeEnum>. Parece innecesario tener que emitir esto, ya que las claves de un EnumMap siempre serán una enumeración. ¿Alguien sabe por qué el método keySet() se construyó de esta manera? He pensado que a veces podría tener algo que ver con que EnumSet sea una clase abstracta, pero seguramente EnumMap podría devolver lo que sea que proporcione el método de fábrica de EnumSet.

¡Salud, todo!

EDIT: Lo siento mucho, el código anterior arroja un CastClassException. Puede obtener el EnumSet usando

EnumSet<SomeEnum> myEnum = EnumSet.copyOf(myMap.keySet()); 

Realmente debería haber comprobado antes de publicar.

+5

Obtienes un 'Set '. ¿Cuál sería la ventaja de tener un 'EnumSet '? –

+0

@PaulBellora Tienes razón, lo anterior está mal. Lo corregiré. Debe ser 'EnumSet myEnum = EnumSet.copyOf (myMap.keySet());' – jalopezp

+0

También aquí hay una bonita vista de la fuente, con estilo en línea javadoc: http://grepcode.com/file/repository.grepcode.com /java/root/jdk/openjdk/6-b14/java/util/EnumMap.java#EnumMap.keySet%28%29 –

Respuesta

8

Creo que es porque el keySet no es un EnumSet. ;)

La razón por la que no lo es es que keySet es una vista en el mapa subyacente.

myMap.keySet().removeAll(keysToRemove); // removes multiple keys. 
+0

Pero, de todos modos, ¿cuál sería el punto? –

+0

Conceptualmente, keySet() es un conjunto de enum o un conjunto de enumeraciones. Si la API se diseñó de manera diferente, podríamos haber tenido una interfaz EnumSet, pero dado que esto sería lo mismo que Establecer, no hay ventaja práctica.Si EnumSet podría proporcionarle methunts específicos de Enum como su tipo de elemento en tiempo de ejecución, tal vez podría hacer la diferencia. –

0

Si usted va a la fuente de esa clase, entonces usted entenderá mejor la scenerio por eso que se vuelve Set. Puede encontrar que por debajo url

http://www.docjar.com/html/api/java/util/EnumMap.java.html

Hope esto le puede ayudar.

¡Disfrútalo!

+0

Eso es genial, ¡no sabía que podía ver la fuente de esto! He estado lidiando con la API desde el principio. Pero sí, veo que el método keySet() devuelve Set keySet, que se define en la superclase, por lo que no podría tenerlo de otra manera. Muchas gracias, lo disfrutaré! – jalopezp

+0

@jalopezp Gracias compinche –

+3

Cuando en las 800 líneas de código en su enlace iba a esperar para encontrar la respuesta a la pregunta? Por favor, publique un fragmento de la parte relevante. – Gabe

3

EnumSet es una implementación de Set que usa una enumeración para representar el espacio de la clave. La clase EnumSet no proporciona métodos no estáticos adicionales, por lo que no habría ninguna razón para devolver un EnumSet en un solo Set.

+0

Mejor respuesta hasta el momento y sencilla . No hacer referencia a los detalles de implementación/no relevante para el diseño de la API) o la mala suposición de que Java no tiene tipos de retorno covariantes (las subclases pueden devolver subclases del valor de retorno en los métodos sustituidos). –

+0

+1 Es mejor mirar el diseño de API que el código de abajo. –

2

Editar: Estaba equivocado, por favor ignórelo.

EnumMap extiende AbstractMap, que declara keySet. AbstractMap no puede declarar que keySet devuelve EnumSet, ya que no es cierto para otras subclases de AbstractMap. Por lo tanto, su tipo de devolución es Set.

+3

Bueno, eso no es cierto, las subclases pueden tener valores de retorno más específicos. Tipos de retorno covariantes desde Java 5. –

Cuestiones relacionadas