implementations example ejemplo collection java collections interface set

example - set java ejemplo



Java: establecer interfaz y diferencias de interfaz de colección (4)

Hay más en un método que su firma.

En este caso, la documentación de estos métodos se ha adaptado a conjuntos, en términos de condiciones previas y posteriores, y terminología.

Acabo de consultar la interfaz de Set y descubrí que en su mayoría (o completamente) solo redeclara funciones que ya están en la interfaz de Collection . Set se extiende a la Collection , ¿no significa eso que la interfaz Set tiene automáticamente todas las funciones de Collection ? Entonces, ¿por qué se vuelven a declarar?

Por ejemplo, Set redeclara esto:

/** * Returns the number of elements in this set (its cardinality). If this * set contains more than <tt>Integer.MAX_VALUE</tt> elements, returns * <tt>Integer.MAX_VALUE</tt>. * * @return the number of elements in this set (its cardinality) */ int size(); /** * Returns <tt>true</tt> if this set contains no elements. * * @return <tt>true</tt> if this set contains no elements */ boolean isEmpty();

Y la declaración en la Collection :

/** * Returns the number of elements in this collection. If this collection * contains more than <tt>Integer.MAX_VALUE</tt> elements, returns * <tt>Integer.MAX_VALUE</tt>. * * @return the number of elements in this collection */ int size(); /** * Returns <tt>true</tt> if this collection contains no elements. * * @return <tt>true</tt> if this collection contains no elements */ boolean isEmpty();

Esto me parece muy redundante. ¿Por qué no simplemente definir la interfaz Set como:

public interface Set<E> extends Collection<E> {}

Creo que no hay una diferencia única entre esas interfaces, ¿verdad?

Por supuesto, no estoy preguntando sobre la diferente semántica / significado de Set . Yo sé eso. Solo estoy preguntando si técnicamente (es decir, para el compilador) tiene alguna diferencia. Es decir, hablando en general:

interface A { void foo(); } interface B extends A { void foo(); } interface C extends A {}

Ahora, ¿hay alguna diferencia entre A , B o C ?

Si bien el contrato (es decir, lo que se dice en la documentación) puede ser realmente diferente para algunas funciones (como para add ), existe una razón válida para redeclararlas: para poder poner una nueva documentación, es decir, para definir el nuevo contrato.

Sin embargo, también hay funciones (como isEmpty ) que tienen exactamente la misma documentación / contrato. ¿Por qué también son redeclarados?


La respuesta está en la API java6 para el conjunto.

"La interfaz Set establece estipulaciones adicionales, más allá de las heredadas de la interfaz Collection, en los contratos de todos los constructores y en los contratos de los métodos add, equals y hashCode. Las declaraciones para otros métodos heredados también se incluyen aquí por conveniencia. Estas declaraciones se han adaptado a la interfaz Set, pero no contienen ninguna estipulación adicional).


Se redecienden porque, incluso si los nombres son iguales, tienen un significado diferente. El método add en el Set es una implementación específica del método genérico add en Collection .

La intención es especificar explícitamente que el método add del Set sea ​​muy diferente del método add de Collection .

¿Por qué no simplemente definir la interfaz Set como:

public interface Set<E> extends Collection<E> {}

Si se ha hecho de esta manera, no habría lugar donde se pueda especificar el contrato de un Set . ¿Cómo sabría que al implementar el método add del Set , no debería permitir duplicados?


Técnicamente para el compilador no hace ninguna diferencia en absoluto.

Sin embargo, un conjunto no puede tener entradas duplicadas, mientras que una colección puede. Esto vale la pena saberlo.

Debido a esto, la semántica de los métodos para los parámetros, los valores de retorno y lo que sucede pueden significar cosas diferentes. Redeclar también permite que el javadoc se vuelva más específico. Por ejemplo para add ():

Set: @return true si este conjunto aún no contiene el elemento especificado

Colección: @return verdadero si esta colección cambió como resultado de la llamada

El significado para el conjunto es más específico.

Incluso para los métodos que no son más específicos, permite que el javadoc sea más agradable. Por ejemplo, para size (): "Devuelve la cantidad de elementos en este conjunto (su cardinalidad)". que está más cerca del lenguaje que la gente usa para los conjuntos matemáticos lo entenderá.

Los documentos API resumen esto diciendo: "La interfaz Set establece estipulaciones adicionales, más allá de las heredadas de la interfaz Collection, en los contratos de todos los constructores y en los contratos de los métodos add, equals y hashCode. Las declaraciones para otros métodos heredados también son incluido aquí para mayor comodidad. (Las especificaciones que acompañan a estas declaraciones se han adaptado a la interfaz de Conjunto, pero no contienen ninguna estipulación adicional).