BT

Disseminando conhecimento e inovação em desenvolvimento de software corporativo.

Contribuir

Tópicos

Escolha a região

Início Notícias Java 8: Expressões lambda e coleções

Java 8: Expressões lambda e coleções

Faltando pouco para o lançamento do Java 8, vale a pena rever o post publicado por Brian Goetz, cobrindo as melhorias na API de coleções do Java: "O Estado do Lambda". A introdução de expressões lambda é uma das funcionalidades mais esperadas do Java 8, e o suporte a elas na Collections API é fundamental para garantir ampla utilização das bibliotecas. Para conhecer mais sobre o que vem sendo feito nessa área do Java, consulte nosso texto sobre o post anterior de Goetz.

Uma vez que não é prático substituir toda a biblioteca Collections, é necessário estendê-la com o suporte a lambdas. O plano é utilizar iteração interna, ou seja, passando um lambda ao forEach() na coleção, como alternativa à implementação externa utilizada atualmente, como por exemplo Iterator e Enumeration. Uma nova interface denominada Stream será adicionada para suportar uma sequência de valores potencialmente sob demanda (lazy), juntamente com métodos como stream() para converter uma coleção em um stream ou fluxo (que pode também ser sob demanda).

Os streams são diferentes das classes gerais da API Collections, pois não possuem armazenamento, podendo ser infinitos ou lidos sob demanda. São em essência processados funcionalmente e podem ser gerados sob demanda. Por exemplo, um Stream pode ser criado para representar números primos, com cada novo elemento produzindo o próximo número na sequência.

A interface Stream também vai trazer uma série de métodos funcionais, incluindo forEach(), filter(), fold(), anyMatch(), map(), e flatMap(). A interface pode ser construída de acordo com o tipo específico de coleção utilizada, ou pode ser implementada de maneira genérica, para possibilitar a utilização de outras classes. Esse modo de operação sob demanda (lazy) significa que o stream pode ser consumido, filtrado e mapeado juntamente com uma operação como findFirst(). Pode ser feito um encadeamento e concluir assim que a primeira equivalência for encontrada, em vez de se iterar por toda a coleção. Veja um exemplo mencionado no artigo "Estado das Coleções", também por Goetz:

Optional<Shape> firstBlue =
 shapes.stream()
  .filter(s -> s.getColor() == BLUE)
  .findFirst();

O pacote java.util.function terá um conjunto inicial de interfaces funcionais como Predicate, Function, UnaryOperator e BinaryOperator, com a ideia de que os desenvolvedores serão capazes de adicionar sua própria interface funcional. O pacote funcional também introduz um novo tipo, Optional, que fornece um mecanismo para representar valores potencialmente nulos. Essa classe wrapper ("invólucro") possui uma única instância de um tipo, ou representa o valor nulo de maneira segura.

Nem todos estão satisfeitos com essa estrutura, como mostra esta longa discussão. Outras linguagens, como Scala e Haskell, ofercem uma visão mais funcional de Optional, como um monad; mas, como Brian Goetz diz que há muitos entendimentos diferentes do conceito de "Optional" que "não é a intenção de tornar o Java em algo como Scala ou Haskell". Embora algumas linguagens de tipagem forte ou de nicho vão mais além em design funcional, a maioria dos milhões de desenvolvedores Java não estará familiarizada com programação funcional, e oferecer o maior benefício para o maior número de desenvolvedores é um objetivo fundamental para a Oracle.

A adição de streams e functions à linguagem Java também possibilita a paralelização de operações. Dado um stream lógico de dados, os resultados podem ser divididos em diferentes níveis de partições e entregues para uma arquitetura de processamento paralelo, como o framework fork/join. A proposta atual introduz o Spliterator, que pode ser utilizado para particionar um bloco maior de dados em blocos menores, apropriados para serem processados em paralelo. Ao oferecer uma maneira genérica de particionar uma estrutura de dados em partes menores, o Spliterator possibilita um particionamento eficiente de dados, ao mesmo tempo permitindo que o framework fork/join opere em um conjunto de dados genéricos.

Finalmente, parece que a paixão pelo lambda está crescendo e influenciando a EL (Expression Language) do Java EE. Anteriormente, havia construções como o LINQ (Language Integrated Query) para realizar processamento de dados, mas com a chegada do suporte a lambda foi decidido que a EL deve adotar parte da sintaxe lambda a fim de aumentar a compatibilidade com a linguagem Java.

Avalie esse artigo

Relevância
Estilo/Redação

Conteúdo educacional

BT