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 deSortedMap
lugar deMap
.SortedMap
instancias deSortedMap
más tiempo para crear que las instancias deMap
normales y también son más potentes. Dado que su módulo ya ha invertido el tiempo para construir unSortedMap
, tiene sentido darle al usuario acceso a su mayor potencia. Además, el usuario podrá pasar el objeto devuelto a métodos que exijan unSortedMap
, así como a aquellos que acepten cualquierMap
.
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);