example - tutorial java arraylist




¿Por qué la enumeración se convierte a ArrayList y no a List en java.utils? (3)

Al regresar a List , promocionará el programa a una interfaz , lo cual es una muy buena práctica. Sin embargo, este enfoque tiene su limitación. Por ejemplo, no puede usar algunos métodos que están definidos para ArrayList y que no existen en la interfaz de List . Consulte esta respuesta para obtener más detalles.

Cito el diseño de API de los Tutoriales de Java ™:

... Está bien devolver un objeto de cualquier tipo que implemente o extienda una de las interfaces de colección. Esta puede ser una de las interfaces o un tipo de propósito especial que extiende o implementa una de estas interfaces.

.. En cierto sentido, los valores de retorno deben tener el comportamiento opuesto de los parámetros de entrada: es mejor devolver la interfaz de recopilación aplicable más específica en lugar de la más general . Por ejemplo, si está seguro de que siempre devolverá un SortedMap , debe dar al método correspondiente el tipo de retorno de SortedMap lugar de Map . SortedMap instancias de SortedMap más tiempo para crear que las instancias de Map normales y también son más potentes. Dado que su módulo ya ha invertido el tiempo para construir un SortedMap , tiene sentido darle al usuario acceso a su mayor potencia. Además, el usuario podrá pasar el objeto devuelto a métodos que exijan un SortedMap , así como a aquellos que acepten cualquier Map .

Dado que ArrayList es esencialmente una matriz, son mi primera opción cuando necesito tener una "colección-matriz". Entonces, si quiero convertir la enumeración en una lista, mi elección sería una lista de matriz.

En cualquier otro caso, todavía es válido escribir:

List<T> list = Collections.list(e);

¿Hay una buena razón por la que el método Collections.list() en el paquete java.utils devuelve una ArrayList<T> lugar de List<T> ?

Obviamente, una ArrayList es una List , pero tengo la impresión de que generalmente es una buena práctica devolver el tipo de interfaz en lugar del tipo de implementación.


Hay una pequeña sobrecarga en los métodos de llamada de una interfaz en lugar de directamente en un objeto.

Esta sobrecarga no suele ser más de 1 o 2 instrucciones del procesador. La sobrecarga de llamar a un método es aún menor si el JIT sabe que el método es final. Esto no es medible para la mayoría de los códigos correctos para usted y para mí, pero para los métodos de bajo nivel en java.utils puede usarse en algunos códigos donde es un problema.

Además, como se ha señalado en otras respuestas, el tipo concreto del objeto que se devuelve (incluso cuando está oculto detrás de una interfaz) afecta el rendimiento del código que lo utiliza. Este cambio en el rendimiento puede ser muy grande, de tal manera que el software de llamada no funciona.

Claramente, los autores de java.utils no tienen forma de saber qué hace todo el software que llama a Collections.list () con el resultado y no hay forma de volver a probar este software si cambian la implantación de Collections.list (). Por lo tanto, no van a cambiar la implantación de Collections.list () para devolver un tipo diferente de Lista, ¡incluso si el sistema de tipos lo permite!

Al escribir su propio software, usted (con suerte) tiene una prueba automatizada que cubre todo su código y una buena comprensión de cómo se interrelaciona su código incluye saber dónde es un problema el rendimiento. Ser capaz de hacer un cambio en un método, sin tener que cambiar las llamadas, es de gran valor mientras el diseño del software está cambiando.

Por lo tanto, las dos compensaciones son muy diferentes.


Descargo de responsabilidad: no soy un autor de JDK.

Estoy de acuerdo en que es correcto escribir su propio código en las interfaces, pero si va a devolver una colección mutable a un tercero, es importante que el tercero sepa qué tipo de List está recuperando.

LinkedList y ArrayList son muy diferentes, en cuanto al rendimiento, para diversas operaciones. Por ejemplo, eliminar el primer elemento de una ArrayList es O(n) , pero eliminar el primer elemento de una LinkedList es O(1) .

Al especificar completamente el tipo de retorno, los autores de JDK están comunicando información adicional , en código inequívoco, sobre qué tipo de objeto le están devolviendo, para que pueda escribir su código para usar este método correctamente. Si realmente necesita una LinkedList , sabe que debe especificar una aquí.

Finalmente, la razón principal para codificar una interfaz sobre una implementación es si cree que la implementación cambiará. Los autores de JDK probablemente piensan que nunca van a cambiar este método; nunca va a devolver una LinkedList o una Collections.UnmodifiableList . Sin embargo, en la mayoría de los casos, probablemente aún haría:

List<T> list = Collections.list(enumeration);




return-type