O estudo da API Stream requer conhecimento de expressões lambda em Java, sendo assim, é interessante dar uma olhada no post “Java 8: Expressões Lambda, Closures, Interfaces Funcionais e um pouco mais” que trata da principal novidade do Java 8, expressões lambdas.
A API Streams, novidade no Java 8, oferece suporte a uma série de operações paralelas sobre coleções para processamento de dados. A principal vantagem dessa API é que ela é uma camada de abstração entre o código que processa os dados e código de baixo nível que contém a lógica de processamento paralelo (multithreading).
O conceito da API Streams é baseado na conversão de uma coleção em uma stream, processamento dos dados em paralelo e a devolução dos dados em uma coleção.
O restante deste post apresenta as principais formas de uso de streams e como essa nova API facilita as coisas quando é preciso iterar em coleções para processar dados.
A API Streams trás mais flexibilidade e eficiência às coleções. Considere a contagem de palavras menores do que 12 caracteres de um texto armazenadas em um ArrayList:
List<String> words = … int count = 0; for(String word : words) { if(word.length() < 12) { count++; } }
O mesmo resultado poderia ser obtido com o uso de streams com o seguinte código:
List<String> words = … long count = words.stream().filter(word -> word.length() < 12).count();
No exemplo acima, uma stream é obtida por meio do método stream() da interface Collection. Após obter a stream, é realizada uma operação intermediária com o método filter() para transformar a stream inicial em outra stream. O método filter() recebe como parâmetro um objeto que implementa a interface Predicate<T> (uma interface funcional que retorna um boolean) e retorna uma nova stream contendo os elementos que satisfaçam a condição do objeto Predicate<T>. O resultado esperado é a quantidade de palavras menores do que 12 caracteres, após obter uma stream contendo as palavras menores, uma operação terminal é realizada na stream obtendo o resultado e inutilizando a stream. A operação terminal é o método count() que retorna a quantidade de elementos da stream.
Operações com streams
Há vários métodos e várias formas de se trabalhar com streams. A seguir são comentados alguns dos métodos mais importantes para manipular streams.
Stream<T> filter(Predicate<? super T> predicate) – Retorna uma stream contendo os elementos que satisfaçam o predicado.
<R> Stream<R> map(Function<? super T,? extends R> mapper) – Retorna uma stream contendo os resultados da aplicação da função dada aos elementos da stream original.
Stream<T> distinct() – Retorna uma stream contendo os elementos distintos da stream de acordo com Object.equals(Object).
Todos esses métodos são da interface Stream. Outras interfaces importantes da API Streams para serem utilizadas em conjunto com Stream são Collector e BaseStream, além das classes Collectors e StreamSupport. O resumo da API Strems pode ser conferido no package java.util.stream.
1 Reply to “Java 8: uma visão geral da API Streams”