Estaba tratando de convertir una matriz int a List y tomé la ruta desconocida de usar Java 8 Stream y se me ocurrió esto
Arrays.stream(arr).boxed().collect(Collectors.toList());
Todavía tengo dificultades para entender completamente esta línea, principalmente,
¿Por qué
Collectors.toList()
en este caso se devuelve una interfaz deArrayList<Integer>
implementaciónList
? ¿Por qué noLinkedList<Integer>
o cualquier otra clase genérica conforme a laList
interfaz? No puedo encontrar nada sobre esto, excepto una breve mención de ArrayList aquí , en la sección de Notas de la API.¿Qué significa el panel izquierdo de ? Obviamente es el tipo de retorno genérico ( en mi código aquí). Y creo que es el argumento de tipo genérico del método, pero ¿cómo se especifican? Miré en el documento de interfaz de Collector y no pude absorberlo.
Stream.collect()
R
ArrayList<Integer>
<R, A>
R
es el tipo genérico del tipo resultante.A
El tipo genérico del tipo de acumulación intermedia del recopilador. Ese es el detalle de implementación de cómo funciona un colector. Divide y conquista, también para el procesamiento paralelo, recoge primero en tipos intermedios.Collectors.toList()
en este caso devuelve unArrayList<Integer>
" Es posible que no devuelva unArrayList
. LaList
implementación no está definida , por lo que no puede confiar en la implementación que devuelve. Como dice el javadoc : "No hay garantías sobre el tipo , mutabilidad, serialización o seguridad de subprocesos de la Lista devuelta".toList()
no está devolviendo unaArrayList
oList
, está devolviendo unaCollector
, que eventualmente creará y devolverá unaList
, también la documentación dice: "... No hay garantías sobre el tipo , mutabilidad, serialización o seguridad de subprocesos de la Lista devuelta; si se requiere más control sobre la Lista devuelta, use toCollection (Supplier) .... "Respuestas:
Es una implementación predeterminada.
ArrayList
se usa, porque es mejor en la mayoría de los casos de uso, pero si no es adecuado para usted, siempre puede definir su propio colector y proporcionarle la fábricaCollection
que desee:Sí,
A
yR
son parámetros genéricos de este método,R
es el tipo de retorno,T
es el tipo de entrada yA
es un tipo intermedio, que aparece en todo el proceso de recopilación de elementos (puede no ser visible y no se refiere a esta función). El comienzo deCollector
'javadoc' define esos tipos (son consistentes en todo el documento):fuente
List<Integer> myList = Arrays.stream(arr).boxed().collect(Collectors.toList());
y llamar solo a los métodos declarados en la interfaz List en myList. De lo contrario, ¿podría ponerme en riesgo si Oracle decide cambiar la implementación predeterminada en Java8u1024 o 15?List
, por lo que, independientemente de la implementación utilizada, el comportamiento es el mismo. Es poco probable que la interfaz se cambie en las versiones más recientes de Java.Como sugiere la definición del método, devuelve una implementación de recopilador con el proveedor de recopilador como
ArrayList
. Por lo tanto, es muy claro a partir de la definición de método a continuación queCollectors.toList
siempre devuelve ArrayList collector (While it's arguable why toList not toArrayList word is used in method name
).<R, A> R collect(Collector<? super T, A, R> collector)
mediosSi hace referencia a los comentarios de la documentación, menciona con precisión cuáles son estos tipos genéricos:
fuente
Collectors.toList()
(primer fragmento)? ¿Es openjdk?