Java Stream.collect em Kotlin: guia completo com exemplos

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Como parar de escrever Stream.collect em Kotlin e começar a viver



Você já migrou de Java para Kotlin e se sentiu como um peixe fora d'água? Especialmente quando se tratava de streams. No Java 8, estávamos acostumados com cadeias de .stream().filter().map().collect(). E no Kotlin — puf! — não tem Stream.collect da forma habitual. Mas não entre em pânico. Na verdade, na biblioteca padrão do Kotlin existe tudo isso, só que mais prático, conciso e sem ruído desnecessário.



Neste artigo, vamos explorar quais análogos do Java 8 Stream.collect existem em Kotlin e mostrar isso com exemplos reais. Se você está procurando a resposta para a pergunta "What Java 8 Stream.collect equivalents are available in the standard Kotlin library?" — está no lugar certo. Vamos abordar as operações mais populares: desde a simples coleta em uma lista até agrupamentos complexos e junção de strings.



Pronto? Vamos nessa!



1. O caso mais simples: toList() e toSet()



Em Java, para coletar o resultado de um stream em uma lista, você escreve:



List<String> result = list.stream()    .filter(s -> s.length() > 3)    .collect(Collectors.toList());


Em Kotlin, isso se transforma em uma única linha sem collect:



val result = list.filter { it.length > 3 }


Sim, você ouviu direito. filter em Kotlin já retorna uma lista. Mas se você precisar especificar explicitamente o tipo da coleção, use toList(), toSet() ou toMutableList():



val numbers = listOf(1, 2, 3, 4, 5, 5)val uniqueNumbers: Set<Int> = numbers.toSet()// Resultado: [1, 2, 3, 4, 5]


Conclusão: em Kotlin, a maioria das operações com coleções (filter, map, flatMap) já retorna uma lista. collect(Collectors.toList()) não é mais necessário.



2. Agrupamento: groupingBy em vez de Collectors.groupingBy



Agrupamento é uma das tarefas mais comuns. Em Java, fica assim:



Map<Integer, List<String>> byLength = list.stream()    .collect(Collectors.groupingBy(String::length));


Em Kotlin, existe a elegante função groupBy:



val words = listOf("gato", "código", "gato", "gatinho")val byLength = words.groupBy { it.length }// Resultado: {4=[gato], 6=[código], 7=[gatinho]}


Mas há um detalhe: groupBy retorna diretamente um Map<K, List<V>>. E se você precisar de algo mais complexo, como contar o número de elementos em cada grupo? Em Java, você usaria Collectors.counting():



Map<Integer, Long> countByLength = list.stream()    .collect(Collectors.groupingBy(String::length, Collectors.counting()));


Em Kotlin, para isso existe groupingBy + eachCount:



val countByLength = words.groupingBy { it.length }.eachCount()// Resultado: {4=1, 6=1, 7=1}


E se você precisar coletar não uma lista, mas, por exemplo, um conjunto? Use groupBy com transformação:



val byLengthSet = words.groupBy(keySelector = { it.length }, valueTransform = { it.uppercase() })// Resultado: {4=[GATO], 6=[CÓDIGO], 7=[GATINHO]}


Dica: se você precisar de algo entre groupBy e groupingBy, use groupingBy — ele é lazy e permite aplicar diferentes agregações (eachCount, fold, reduce).



3. Junção de strings: joinToString() em vez de Collectors.joining()



Em Java, a junção de strings com um separador:



String joined = list.stream()    .collect(Collectors.joining(", "));


Em Kotlin, isso é ainda mais simples:



val words = listOf("Kotlin", "Java", "Python")val joined = words.joinToString(",                

Blogs

Book Recommendations