Eu estava tentando converter uma matriz int em List e segui a rota desconhecida de usar o Java 8 Stream e criei essa
Arrays.stream(arr).boxed().collect(Collectors.toList());
Eu ainda tenho dificuldade para entender completamente essa linha, principalmente,
Por que
Collectors.toList()
, neste caso, retorna uma interface deArrayList<Integer>
implementaçãoList
? Por que nãoLinkedList<Integer>
ou qualquer outra classe genérica em conformidade com aList
interface? Não consigo encontrar nada sobre isso, exceto por uma breve menção de ArrayList aqui , na seção Notas da API.O que significa o painel esquerdo ? Obviamente é o tipo de retorno genérico ( no meu código aqui). E eu acho que é o argumento de tipo genérico do método, mas como eles são especificados? Olhei para Collector interface de doc e não foi capaz de absorvê-lo.
Stream.collect()
R
ArrayList<Integer>
<R, A>
R
é o tipo genérico do tipo resultante.A
o tipo genérico do tipo de acumulação intermediária do coletor. Esse é o detalhe da implementação de como um coletor funciona. Ele divide e conquista, também para processamento paralelo, coleta primeiro em tipos intermediários.Collectors.toList()
, neste caso, retorna umArrayList<Integer>
" Ele pode não retornar umArrayList
. AList
implementação é indefinida , portanto você não pode confiar em qual implementação ela retorna. Como o javadoc diz: "Não há garantias sobre o tipo , mutabilidade, serialização ou segurança de thread da Lista retornada;"toList()
não está retornando umArrayList
ouList
- está retornando aCollector
, que eventualmente criará e retornará aList
- também a documentação declara: "... Não há garantias quanto ao tipo , mutabilidade, serialização ou segurança de thread da Lista retornada; se for necessário mais controle sobre a lista retornada, use toCollection (Supplier) .... "Respostas:
É uma implementação padrão.
ArrayList
é usado, porque é o melhor na maioria dos casos de uso, mas se não for adequado para você, você sempre pode definir seu próprio coletor e fornecer fábrica para oCollection
que deseja:Sim,
A
eR
são parâmetros genéricos desse método,R
é o tipo de retorno,T
é o tipo de entrada eA
é um tipo intermediário, que aparece em todo o processo de coleta de elementos (pode não ser visível e não se refere a essa função). O início doCollector
javadoc define esses tipos (eles são consistentes em todo o documento):fonte
List<Integer> myList = Arrays.stream(arr).boxed().collect(Collectors.toList());
e chamar apenas métodos declarados na interface List em myList. Caso contrário, eu estaria potencialmente me colocando em risco, se a Oracle decidir alterar a implementação padrão em Java8u1024 ou 15?List
, portanto, independentemente da implementação usada, o comportamento é o mesmo. É improvável que a interface seja alterada nas versões mais recentes do java.Conforme a definição do método sugere, ele retorna uma implementação do coletor com o fornecedor do coletor como
ArrayList
. Portanto, é muito claro na definição do método abaixo queCollectors.toList
sempre retorna o coletor ArrayList (While it's arguable why toList not toArrayList word is used in method name
).<R, A> R collect(Collector<? super T, A, R> collector)
meiosSe você se referir aos comentários da documentação, ele menciona com precisão o que são esses tipos genéricos:
fonte
Collectors.toList()
(primeiro trecho)? É openjdk?