2011-11-04 8 views
8

Desde el Java 6 TreeSet<E> Documentación:de Java TreeSet <E> remove (Object) no toma un E

boolean remove(Object o): 
    Removes the specified element from this set if it is present. 

¿Por qué aceptar un objeto de esta vez de tipo genérico E? Los únicos objetos que se pueden agregar son del tipo E, por lo que se deduce que el único tipo extraíble debe ser del tipo E.

+5

relacionado: http://stackoverflow.com/questions/857420/what-are-the-reasons-why-map-getobject-key-is-not-fully-generic –

+0

posible duplicado de [¿Por qué no son Java? Las colecciones eliminan los métodos genéricos?] (Http://stackoverflow.com/questions/104799/why-arent-java-collections-remove-methods-generic) – PhoneixS

Respuesta

4

remove(), como get() se requiere para trabajar cuando se les da un igual elemento (en términos de .equals()). En Java, es posible (y en algunos casos, requerido) que los objetos de diferentes clases sean iguales. Por lo tanto, no debe restringir el tipo.

0

Bueno, cada E también es un Objeto, y quizás usted tenga la E no como E en el momento (por ejemplo, desde una fuente de evento), que lo hace más conveniente para usted. De lo contrario, solo tiene que lanzarlo a E solo para eliminarlo.

Desde el punto de vista de la igualdad esto no importa: la dirección de referencia del objeto dado se prueba si es igual al contenido de un conjunto, por lo que no importa de qué clase se trata.

9

Tomando la respuesta desde el primer comentario publicado:

Mito:

Un mito popular es que es tonto y el mal, pero era necesario porque de compatibilidad con versiones anteriores. Pero el argumento de compatibilidad es irrelevante; la API es correcta si tiene en cuenta la compatibilidad con o no.

razón real:

De manera uniforme, los métodos de Java Collections Framework (y el Google Colecciones Biblioteca también) nunca se restringen los tipos de sus parámetros excepto cuando es necesario para prevenir la colección de conseguir roto.

leer más aquí: Why does Set.contains() take an Object, not an E?

0

Esto es realmente un problema. Si alguien llama al remove(o) y o el tipo no es E, generalmente es un error de programación que intenta eliminar algo incorrecto. La verificación de tipo no pudo protegernos del error.

Aunque un buen IDE (IntelliJ) puede detectar tales problemas y advertirnos, los diseñadores de API deberían haber proporcionado una firma más precisa para utilizar la verificación del tipo de compilador. (IDE engaña aquí -. Conoce el significado de Set.remove() porque es una API estándar IDE no proporcionará la misma ayuda para las API personalizados)

Para API de consulta como , que está bien aceptar una E argumento no y el retorno un falso trivial Así que podemos tener ambas cosas

boolean contains(Object o); 
boolean contains2(E o); 

Para API mutación como remove(), es discutible si se debe aceptar un argumento no E.Sin embargo, el debate va a ser discutible, dada la realidad del borrado: en realidad no hay otra opción que aceptar el argumento no E y guardar silencio al respecto. Todavía podemos tener dos métodos

boolean remove(Object o); 
boolean remove2(E o); 

En la mayoría de los casos, los programadores pueden llamar contains2/remove2 para la seguridad de tipos adicional.

+0

¿Estás diciendo que 'remove2/contains2' son métodos TreeSet? No veo eso en la api ... – ComputerDruid

Cuestiones relacionadas