Como faço para converter um Java 8 IntStream em uma lista?

283

Estou olhando os documentos para o IntStreame vejo um toArraymétodo, mas não há como ir diretamente para umList<Integer>

Certamente existe uma maneira de converter um Streampara um List?

Eric Wilson
fonte
Tente este link: stackoverflow.com/questions/14830313/…
Vaibhav Jain 15/14
2
@KarlRichter A outra pergunta não fornece uma lista digitada. Além disso, essa pergunta foi de quatro anos atrás e tem uma resposta com mais de 300 votos. Por que estamos tentando mesclá-lo agora?
Eric Wilson

Respostas:

541

IntStream::boxed

IntStream::boxedtransforma um IntStreamem um Stream<Integer>, que você pode collecttransformar em um List:

theIntStream.boxed().collect(Collectors.toList())

O boxedmétodo converte os intvalores primitivos de um IntStreamem um fluxo de Integerobjetos. A palavra "boxe" nomes do intIntegerprocesso de conversão. Consulte o Tutorial do Oracle .

Ian Roberts
fonte
1
@skiwi Quero dizer, que todas as outras respostas são desnecessárias após essa, pois não seriam tão naturais.
Dmitry Ginzburg
1
Obrigado, eu ainda não tinha visto o método em caixa e funcionou como um encanto.
Twreid
Além disso: acho que esses códigos ficam um pouco mais curtos, claros e mais bonitos se você usar uma importação estática de toList. Isso é feito colocando o seguinte entre as importações do arquivo: static import java.util.stream.Collectors.toList;. Em seguida, a chamada a cobrar será exibida apenas .collect(toList()).
Lii 29/06
1
No Eclipse, é possível fazer o IDE adicionar uma importação estática para métodos. Isso é feito adicionando a Collectorsclasse em Preferências -> Java -> Editor -> Assistente de Conteúdo -> Favoritos . Depois disso, você só precisa digitar toLino hit Ctr + Space para que o IDE preencha toListe adicione a importação estática.
Lii 29/06
2
Estava rasgando meu cabelo para fora sobre o que havia de errado com o que eu tinha tentado, obrigado por apontar a boxed()parte
K Raphael
16

Você também pode usar o mapToObj () em um fluxo, que utiliza uma IntFunction e retorna um fluxo com valor de objeto que consiste nos resultados da aplicação da função fornecida aos elementos desse fluxo.

List<Integer> intList = myIntStream.mapToObj(i->i).collect(Collectors.toList());
Ida Bucić
fonte
4
Em um golpe de ironia, é para isso que boxed()está delegando.
Makoto
9

É possível usar coleções primitivas disponíveis nas Coleções Eclipse e evitar boxe.

MutableIntList list = 
    IntStream.range(1, 5)
    .collect(IntArrayList::new, MutableIntList::add, MutableIntList::addAll);

Nota: Sou colaborador do Eclipse Collections.

Nikhil Nanivadekar
fonte
6
Embora Eclipse coleções são geralmente muito útil, isso não parece que está fazendo alguma coisa mais fácil em todos os :)
Ben
1
Desde o EC 9.0, você pode criar uma lista primitiva a partir de um fluxo primitivo. MutableIntList list = IntLists.mutable.withAll(IntStream.range(1, 5))
Donald Raab
1
Isto é o que eu estava procurando .. boxe o fluxo de int para Integer ou objeto é coisa diferente
Vikash
2

Encontre o exemplo a seguir de encontrar quadrado de cada elemento int usando o Java 8: -

IntStream ints = Arrays.stream(new int[] {1,2,3,4,5});       
List<Integer> intsList = ints.map(x-> x*x)
          .collect(ArrayList<Integer>::new, ArrayList::add, ArrayList::addAll);
Vikash
fonte
0

Você pode usar o método de coleta:

IntStream.of(1, 2, 3).collect(ArrayList::new, List::add, List::addAll);

De fato, isso é quase exatamente o que Java está fazendo quando você chama .collect (Collectors.toList ()) em um fluxo de objetos:

public static <T> Collector<T, ?, List<T>> toList() {
    return new Collectors.CollectorImpl(ArrayList::new, List::add, (var0, var1) -> {
        var0.addAll(var1);
        return var0;
    }, CH_ID);
}

Nota: O terceiro parâmetro é necessário apenas se você deseja executar uma coleção paralela; para coleta seqüencial, fornecendo apenas os dois primeiros será suficiente.

Harry Jones
fonte