Buscar

Programação Funcional em Java

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 7 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 7 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

37 \
_lambda
Você sabe ordenar uma lista? Sabe selecionar os elementos de uma 
lista a partir de um critério? E extrair os valores de uma determina-
da propriedade do objeto de uma lista? 
São tarefas comuns que estamos cansados de repeti-las. Mas será 
que conhecemos a melhor forma de escrevê-las? Há como fazer de 
forma mais concisa, sem perder a legibilidade?
Neste artigo vamos mostrar o que muda nessas tarefas do dia a dia 
ao utilizar bibliotecas como o Google Guava e LambdaJ, que adi-
cionam um sabor funcional ao Java atual. Depois chegaremos ao 
futuro Java 8, para ver como o lambda e os defender methods estão 
mudando a linguagem em direção ao funcional. 
Chegando ao 
Lambda 
no Java 8
Como melhorar seu código atual (e futuro) 
utilizando funções Lambda.
Paulo Silveira | paulo.silveira@caelum.com.br 
Bacharel e mestre em computação pela Universidade de São Paulo. Fundador do GUJ.com.br, trabalha com Java há 11 anos. É um 
dos responsáveis técnicos pelos cursos da Caelum.
Raphael Lacerda | raphael.lacerda@caelum.com.br 
Pós-graduado em Engenharia de Sistemas. Atua como analista de sistemas no Banco do Brasil e ministra cursos na Caelum Bra-
sília. Entusiasta por expressividade de código e DSLs. Possui as certificações SCJP e SCWCD. É um dos responsáveis técnicos pelos 
cursos da Caelum.
/ 38 
Programação funcional é um tema em alta mesmo no mercado corporativo. Sua ascensão ficou bem 
apresentada pelo artigo de Steve Vinosky, “Welcome 
to the functional web”, e pode ser claramente vis-
ta pela grande quantidade de linguagens funcionais 
(ou ao menos com um pouco mais de características 
funcionais) na JVM. Scala e Clojure são expoentes 
aqui. Os artigos na MundoJ revelam também essa 
tendência.
Java é orientada a objetos. O que poderíamos 
aproveitar do conceito do paradigma funcional para 
melhorar alguns pontos subjetivos do nosso código: 
legibilidade, expressividade e concisão? Usando ape-
nas a API padrão, muito pouco. Ficamos reféns das 
longas e “verborrágicas” classes anônimas, ou de la-
ços que se repetem exaustivamente. 
 Como o Java e o JCP estão reagindo a essa ten-
dência? Certamente a linguagem está bastante de-
fasada, não só em relação às outras com pequena 
penetração no mercado corporativo, como Scala e 
Clojure, mas também do Ruby e Python, sem contar 
o C#, que já possui recursos funcionais muito avan-
çados há bastante tempo.
Para a oitava edição da plataforma, prevista para 
setembro de 2013, teremos a inclusão de uma sin-
taxe própria para definir lambdas, em estilo muito 
similar a essas linguagens. Veremos, neste artigo, 
como será essa nova sintaxe, junto com algumas no-
vidades da JSR 335.
Mas precisamos esperar ainda um ano para tirar 
proveito de uma API mais elaborada, além da sintaxe 
adocicada?
Ao final deste artigo você conhecerá duas biblio-
tecas funcionais: Guava e LambdaJ. Elas possuem 
uma robusta API para facilitar o trabalho do dia a 
dia, em especial relacionado a coleções. O LambdaJ 
vai além: abusa das proxies dinâmicas para mimeti-
zar uma sintaxe diferente.
Você pode ler este artigo de maneira relativa-
mente independente: mostraremos cada uma das 
abordagens para resolver problemas parecidos, en-
volvendo simples manipulações de coleções, utili-
zando a classe Palestrante. A Listagem 1 mostra essa 
classe, que implementa Comparable de forma trivial 
e possui, como atributos, o número de posts do pa-
lestrante no GUJ, um id e um nome.
Listagem 1. Implementação de Palestra e Palestran-
te. 
public class Palestrante implements 
Comparable<Palestrante> {
 private final int id;
 private final String name;
 private final int postsNoGuj;
 private boolean favoritado;
 public void favoritar() {
 favoritado = true;
 }
 @Override
 public int compareTo(Palestrante o) {
 Objects.requireNonNull(o);
 return Integer.compare(this.id, o.getId());
 }
}
Algumas tarefas do dia a dia com o 
Java sem esteróides
 Vamos atacar os problemas triviais sem utilizar 
nenhuma biblioteca de fora do Java. Se temos uma 
lista de Palestrante chamada palestrantes, como 
costumamos imprimir todos seus nomes? Escreve-
mos um foreach:
for (Palestrante p : palestrantes) {
 System.out.println(p);
}
Para somar todos seus posts, temos outro sim-
ples laço:
int soma = 0;
for (Palestrante p : palestrantes) {
 soma += p.getPostsNoGuj();
}
Para filtrar todos os que já fizeram mais de 500 
posts no GUJ, e depois favoritá-los, o código também 
é bastante simples:
for (Palestrante p : palestrantes) {
 if (p.getPostsNoGuj() > 500)
 p.favoritar();
}
Para orderná-los através de posts, criamos um 
Comparator. Podemos fazer isso em outra classe, 
mas é comum ficar numa classe anônima:
Comparator<Palestrante> comparador = new 
Comparator<Palestrante>() {
 public int compare(Palestrante o1, Palestrante o2) {
 if (o1.getPostsNoGuj() < o2.getPostsNoGuj()) 
 return -1;
 if (o1.getPostsNoGuj() > o2.getPostsNoGuj()) 
 return 1;
 return 0;
 }
};
Collections.sort(palestrantes, comparador);
São quatro curtos códigos que estamos cansados 
de escrever no dia a dia. Como eles ficam adicionan-
do um pouco de programação funcional? Será que 
torná-los curtos facilitaria a legibilidade? Melhora-
ria a forma de pensar?
39 \
Google Guava
O Guava é um apanhado geral de funcionalidades 
que os desenvolvedores do Google usam nos projetos 
Java da empresa. A biblioteca abrange várias áreas 
como coleções (inclusive criando outros tipos de col-
lections como o MultiSet), concorrência, I/O, reflec-
tion, validação, dentre outros. Eles resolveram juntar 
todos esses utilitários em um projeto só, dando ori-
gem ao Guava. Está disponível para quem faz geren-
ciamento de dependências com o Maven, Gradle, Ivy 
e Buildr e tem uma boa documentação.
A própria biblioteca diz que para tentar atingir 
uma programação funcional utilizando Java 7 é só 
através de um código estranho e muito verboso, ba-
sicamente utilizando classes anônimas, portanto ela 
traz funcionalidades para reverter esse quadro.
O projeto contém algumas classes e interfaces 
que ajudam na programação no estilo funcional como 
Function, Predicate, FluentIterable e uma classe uti-
litária Collections2. Em suma, podemos fazer uma 
operação básica como filtragem com praticamente 
uma combinação de todas elas, o que muda é que, por 
exemplo, a classe FluentIterable provê essa funciona-
lidade seguindo o padrão FluentInterface.
Como primeiro exemplo, a partir de uma lista de 
participantes, deve-se obter uma lista dos nomes em 
maiúsculo. Para isso vamos utilizar os métodos da 
classe FluentIterable from e trasform.
System.out.println(FluentIterable.from(palestrantes)
.transform(new Function<Palestrante, String>() {
 @Override
 public String apply(Palestrante palestrante) {
 return palestrante.getName().toUpperCase();
 }
}));
Agora vamos para um problema mais comum. A 
partir de uma lista de palestrantes, obter somente 
aqueles que tiveram mais do que 500 posts.
System.out.println(FluentIterable.from(palestrantes).filter(
 new Predicate<Palestrante>() {
 @Override
 public boolean apply(Palestrante palestrante) {
 return palestrante.getPostsNoGuj() > 500;
 }
}));
Extraindo métodos e utilizando imports estáti-
cos, conseguimos um código mais sucinto:
System.out.println(from(palestrantes).filter(
 comPostsMaiorQue500()));
Para fazer funções de ordenação, vamos usar a 
classe Ordering, que é um comparador fluente e pode 
ser usado para manipular, estender e fazer uso de 
Comparators. Ela possui alguns métodos utilitários 
para ordenação, como levar em conta valores null, 
ordem reversa, ordem lexicográfica,verificar se a lista 
está ordenada, dentre outros. Vamos fazer três exem-
plos rápidos de ordenação. Primeiramente ordenar 
uma lista desordenada de participantes pela sua or-
dem natural (definida pela interface Comparable). 
List<Palestrantes> palestrantesOrdenadosPorId = 
Ordering.natural().sortedCopy(palestrantesDesordenados);
Depois vamos ordenar por nome, para isso vamos 
criar utilizar a classe Function.
Function<Palestrante, String> ordernacaoPorNome = new 
 Function<Palestrante, String>() {
 @Override
 public String apply(Palestrante p) {
 return p.getName();
 }};
List<Palestrante> palestrantes =Ordering.natural().
 onResultOf(ordernacaoPorNome).
 sortedCopy(palestrantes);
Por fim ordená-los por nome e posts no guj, onde 
nomeComparator e postsComparator representam 
referências para classes anônimas que implementam 
a interface Comparator. 
 List<Palestrante> palestrantesNomePosts = 
 Ordering.from(nomeComparator).compound(
 postsComparator).sortedCopy(palestrantes);
Concluindo, a principal vantagem do Guava em 
relação à API nativa do Java é que ele possui alguns 
métodos de suporte mais efetivos, entretanto criar 
classes anônimas Function e Predicate não muda 
muito em quantidade/expressividade de código.
LambdaJ
LambdaJ é uma bibioteca para manipular cole-
ções de uma forma mais simples e natural. Foi criada 
por Mario Fusco e surgiu devido à necessidade de en-
tender melhor uma parte do domínio que lidava com 
interações em coleções em um projeto que ele parti-
cipava. A biblioteca foi desenhada como sendo uma 
DSL interna para o Java. Segundo Fusco, esse código 
era complexo, repetitivo e de difícil leitura. Os desen-
volvedores gastavam mais tempo tentando adivinhar 
o que um determinado loop fazia do que escrevendo-
-o. E ele afirma: “...códigos como este são feitos para 
o computador ler e não o programador...”. Bom, a si-
tuação parece familiar para você?
Ela é muito fácil de se utilizar, tem uma boa do-
cumentação e basta ir ao site do projeto para baixá-
-la, inclusive já possui um jar único com todas as de-
pendências e está disponível também para quem faz 
o gerenciamento com o Maven. Na parte técnica, ela 
faz muito uso de proxy e reflexão, o que a torna mais 
/ 40 
expressiva que as anteriores, todavia um pouco me-
nos eficiente com relação ao desempenho. Recomen-
da-se verificar na página do projeto a sua análise de 
desempenho e a questão toda pode se resumir a um 
trade-off, perdendo um pouco no desempenho para 
ganhar na expressividade de código. Sua principal 
classe é a Lambda, que contém uma série de métodos 
(funções) estáticos.
Inicialmente podemos imprimir o nome de todos 
os participantes, para isso vamos utilizar a função 
joinFrom.
 System.out.println(joinFrom(palestrantes).getName());
O import estático do método joinFrom foi feito 
para facilitar a leitura. Agora vamos ordenar os par-
ticipantes a partir da quantidade de posts, para isso 
vamos utilizar o método sort.
 List<Palestrante> participantesOrdenadosPorPost = 
 sort(palestrantes, on(Palestrante.class).
 getPostsNoGuj());
O item de comparação é obtido a partir do méto-
do on. Podemos obter uma expressividade melhor ao 
extrair a comparação para um método privado. 
 List<Palestrante> participantesOrdenadosPorPost =
 sort(palestrantes, porPostsNoGuj());
A classe Lambda possui método de agregação 
como avg, max e min. Exemplo:
 int totalDePosts = sumFrom(palestrantes).
 getPostsNoGuj();
Agora a partir de uma lista de participantes, va-
mos colocar todos os nomes em maiúsculo. Primeiro 
vamos extrair o nome dos participantes. Para isso, 
será usado o método extract.
 List<String> nomesDosPalestrantes = 
 extract(palestrantes, on(Palestrante.class).
 getName());
Com o nome dos participantes, o objetivo agora é 
colocá-los em letra maiúscula. Para isso vamos usar o 
método convert e a interface do LambdaJ Converter. 
Ela especifica como converter um objeto de um tipo 
em outro. No exemplo será de String para String.
 List<String> nomesMaiusculos = convert(
 nomeDosPalestrantes, new Converter<String, 
 String>(){
 @Override
 public String convert(String nome){
 return nome.toUpperCase();
 }});
Podemos fazer um pequeno refactoring para tor-
ná-lo mais legível:
List<String> nomesMaiusculos =
 convert(nomeDosPalestrantes, paraMaiusculo());
Temos agora o seguinte problema, mais comum 
no dia a dia do desenvolvedor. A partir de uma lista 
de palestrantes, selecionar os palestrantes com mais 
de 500 posts e colocá-los como favoritos. Já sabemos 
como é essa solução usando Java puro, ocupando al-
gumas linhas de código. Já com LambdaJ tudo se re-
solve com apenas uma linha. Para isso vamos utilizar 
o método select para selecionar os participantes e o 
método forEach para percorrer essa lista e favoritá-
-los. Também iremos usar o método having e grea-
terThanOrEqualTo, ambos do Hamcrest, uma depen-
dência do LambdaJ.
forEach(select(palestrantes,having(on(
 Palestrante.class).getPostsNoGuj(),
 greaterThanOrEqualTo(500)))).favoritar();
Poderia ter sido usado o método and e or para 
adicionar outras restrições. Agora a leitura ficou fá-
cil, todavia ainda pode ser melhorada, tornar-se mais 
expressiva. Vamos extrair a parte de comparação para 
um método privado e parametrizar o valor a ser com-
parado.
forEach(select(palestrantes, 
 comPostsMaiorQue(500))).favoritar();
O LambdaJ também possui uma classe Lambda-
Collection que segue o padrão Fluent Interface assim 
como o FluentIterable do Guava. Vamos utilizá-la 
no seguinte problema: tendo uma lista de palestras 
(considere a nova classe Palestra abaixo), selecionar 
as palestras que tiveram uma votação superior a 100, 
então a partir desta selecionar os seus palestrantes 
ordenados por quantidade de posts. Para isso vamos 
utilizar os métodos with, que devolve uma referência 
para uma LambdaCollection, retain, que tem funcio-
namento análogo ao select e o extract que já vimos 
previamente:
 public class Palestra {
 private final String titulo;
 private final Palestrante palestrante;
 private final int quantidadeDeVotos;
 // getters e constructor omitidos
 }
 List<Palestrante> palestrantes = with(palestras).
 retain(having(on(Palestra.class). 
 getQuantidadeDeVotos(), 
 greaterThanOrEqualTo(100))). 
 extract(on(Palestra.class).getPalestrante()). 
 sort(on(Palestrante.class).getPostsNoGuj());
41 \
Novamente, com uma refatoração, temos:
 List<Palestrante> palestrantes = with(palestras).
 retain(comQuantidadeDeVotosMaiorQue(100)).
 extract(palestrante()).sort(porPostsNoGuj());
Por fim, recomendamos olhar nas referências 
para verificar as outras funcionalidades da biblioteca, 
alguns métodos como index, group e project podem 
resolver problemas de uma forma mais concisa do 
que a sua atual solução. Por exemplo, em um cenário 
de aplicações distribuídas, em que há a necessidade 
de se serializar objetos para transferi-los entre JVMs 
diferentes, o padrão DTO pode ser utilizado. Então 
podemos chegar ao seguinte código, caso queiramos 
instanciar objetos do tipo DadosPessoais que tam-
bém possuam o atributo nome:
List<DadosPessoais> palestrantesParaTransferencia = 
 project(palestrantes,DadosPessoais. 
 class,on(Palestrante.class).
 getId(),on(Palestrante.class).getName());
Lambda no Java 8
Apesar de estar planejado apenas para setembro 
de 2013, você já pode utilizar milestones do JDK8, 
disponíveis para os principais sistemas operacionais, 
inclusive para o Mac OSX. Otime do lambda do JDK 
8 é liderado por Brian Goetz, muito conhecido por 
seu livro de programação concorrente na plataforma 
Java. 
Direto ao código. Dada uma List<Palestrante> 
palestrantes, como imprimir todos eles?
 palestrantes.forEach(new Block<Palestrante>() {
 public void apply(Palestrante p) {
 System.out.println(p);
 }
 });
Quem conhece um pouco da API de coleções sabe 
que não há um método forEach dentro de List, nem 
em suas principais superinterfaces: Collection e Ite-
rable. Para esse código funcionar, além dessa interfa-
ce Block precisar existir, esse método forEach precisa 
ter sido adicionado. E no Java 8 ele foi, dentro da in-
terface Iterable.
Isso é bastante perigoso: evoluir uma interface 
adicionando novos métodos quebram classes exis-
tentes que a implementavam! Como o time fez isso, 
minimizando os riscos? Eles adicionaram suporte aos 
extension methods. Se você olhar o código-fonte da 
interface Iterable, encontrará o seguinte método:
 void forEach(Block<? super T> block) default {
 Iterables.forEach(this, block);
 }
Agora você pode criar métodos em interfaces no 
Java e colocar uma implementação default, deso-
brigando suas implementadoras de o reescreverem. 
Algo parecido com os mixins do Ruby e com os traits 
do Scala, mas ainda sem a possibilidade de conter 
atributos não-estáticos. A palavra-chave default, 
dentro de um método de interface, é quem faz essa 
mágica e define-o como extension method. Classes 
que implementam Iterable não precisarão reescrever 
esse método.
Há muitas interfaces e classes novas no Java 8 nos 
pacotes lang e util. Iterables, Comparators, MapStre-
am, BiVal/BiValue são apenas algumas delas, além do 
pacote java.util.functions, onde a Block se encontra. 
Trabalharemos com elas no nosso dia a dia e vamos 
utilizar algumas delas nessa seção.
 palestrantes.forEach(p -> { System.out.println(p); });
Apesar de trazer muitas novidades, um lambda 
não pode ser criado de qualquer maneira. O código 
abaixo não compila:
 Object o = p -> { System.out.println(p); };
Uma expressão lambda precisa sempre ser atri-
buída/inferida para uma interface/class abstrata que 
possui apenas um único método abstrato (antiga-
mente chamadas de SAM: single abstract method). 
A especificação, ainda em andamento, as chamam 
agora de functional interfaces. Por exemplo, para um 
Runnable, conseguimos inferir um lambda que não 
> Na edição número 52 da MundoJ, Bruno Kioshita fez uma excelente introdução sobre paradigma funcional, explicando conceitos 
como Functions, Predicates, dentre outros. Também abordou como fazer o uso da biblioteca Apache Functor, que possui ideias 
parecidas com as bibliotecas que serão descritas neste artigo. Por isso, iremos focar essencialmente na prática de como utilizar funções 
em Java, atualmente com bibliotecas externas e futuramente com o Lambda no Java 8.
> Já na edição 53, Leandro Moreira fez um artigo de introdução à linguagem Clojure, remetendo a alguns conceitos de Programação 
Funcional. Nesta mesma edição Hugo Ferreira descreve vários problemas que podem ser resolvidos com programação Objeto-Funcional 
e, por fim, Rafael Ferreira traz o recurso de pattern matching da linguagem funcional Scala.
mais programação funcional na MundoJ/
/ 42 
recebe argumentos:
 Runnable r = () -> { System.out.println(); };
Como o compilador sabe que esse conteúdo vai 
para dentro do método run()? Pois é o único método 
abstrato da interface. Assim como o método apply(T 
o) é o único da interface Block<T>.
Podemos ir mais adiante. Quando o lambda vai 
realizar apenas uma única invocação de método com 
todos os parâmetros recebidos, podemos criá-lo atra-
vés de uma referência para um método:
 palestrantes.forEach(System.out::println);
Assustador? O compilador vai inferir que o Block 
a ser passado para o forEach vai ser uma invocação 
do método println em cima de System.out, passando 
o único parâmetro que esse Block pode receber: um 
palestrante. Se você tivesse passado uma referência 
para um método que recebe mais de um parâmetro, o 
compilador não conseguiria inferir o lambda!
Vale lembrar que isso não é um “method lite-
ral”, da mesma forma que temos class literals (como 
String.class, por exemplo). Fazer Method m = System.
out::println, ou algo semelhante, não compila. Uma 
referência a um método nada mais é que outra for-
ma de escrever um lambda, então possui as mesmas 
restrições: há necessidade de uma interface funcional 
envolvida na expressão.
Assim como o forEach, há muitos novos exten-
sions methods na interface Iterable, conhecidos dos 
programadores funcionais: map, reduce, filter, grou-
pBy, mapped etc. Para pegar o número de posts que 
cada Palestrante tem no GUJ, fazemos:
Iterable<Integer> posts = palestrantes.map(
 p -> p.getPostsNoGuj());
Nesse caso nem precisamos usar as chaves depois 
dos parâmetros. Não precisamos utilizá-los quando 
o conteúdo do método é uma instrução de return. O 
mesmo ocorre com os parênteses dos parâmetros, 
que são opcionais no caso de ser apenas um. Em ou-
tras palavras, poderíamos escrever:
Iterable<Integer> posts = palestrantes.map((p) 
 -> { return p.getPostsNoGuj(); } );
Ou ainda podemos usar a notação de method re-
ference:
Iterable<Integer> posts = 
 palestrantes.map(Palestrante::getPostsNoGuj);
Dado que temos os inteiros, podemos somá-los 
com o reduce (similar ao foldLeft ou inject em outras 
linguagens):
Integer total = posts.reduce(0, (total, proximo) 
 -> total+proximo);
O reduce recebe o valor inicial da conta, para de-
pois aplicar, item a item, o lambda dado. Esse lambda 
possui dois parâmetros e será inferido a uma imple-
mentação da nova interface BinaryOperator.
E para filtrar quem tem mais de 500 posts no 
GUJ? Passamos um lambda para ser utilizado como 
implementação do método test da nova interface 
Predicate:
 palestrantes.filter(p -> p.getPostsNoGuj() > 500);
Se você quer invocar o método favoritar em cada 
um desses palestrantes, basta utilizar o forEach que 
já conhecemos:
palestrantes.filter(p -> p.getPostsNoGuj() > 500).
 forEach(Palestrante::favoritar); 
Quer finalmente ordená-los? Finalmente há o 
método sort na interface list!
 palestrantes.sort((p1, p2) -> …. )
Passando seu Comparator como argumento, po-
dendo ser inferido por um lambda.
Com esses novos recursos, o código Java se apro-
xima ao de linguagens como Scala e Ruby. O mesmo 
código em Java, Scala e Ruby, sem abusar muito de 
outros recursos da linguagem (como o underscore do 
Scala), ficaria:
palestrantes.map(Palestrante::getPostsNoGuj).
 reduce(0, (n, x) -> n+x);
palestrantes.map(_.postsNoGuj).fold(0)(n,x => n+x)
palestrantes.map(&:postsNoGuj).inject(0){|n,x| n+x}
Esse foi apenas um sucinto começo do que está 
por vir. Vale conhecer todos os métodos dentro de 
Iterable, assim como as interfaces do java.util.func-
tions e as novas superinterfaces das collections. Há 
ainda references para construtores, novos métodos 
em classes importantes do Java 8 e pequenas melho-
rias por toda API. Será um grande passo para a pla-
> Existe também o já conhecido projeto Apache Collections, que possui algumas novas interfaces e classes utilitárias para manipular 
coleções.
/ mais projetos: Apache Collections
43 \
> “Herança e Composição – os princípios por trás dos 
padrões”, ed. 39 da MundoJ – Eduardo Guerra
> “JPA 2: Os novos recursos inspirados no Hibernate”, ed. 
39 da MundoJ – Paulo Silveira e Raphael Lacerda
> “Enums desmistificadas”, ed. 26 da MundoJ – Alexandre 
Gazola
> Série “Design patterns para um Mundo Real”, eds. 21, 22 
e 23 da MundoJ – Rodrigo Yoshima
para saber mais/ 
taforma. Ao mesmo tempo, algunsoutros itens ain-
da ficaram de fora, como a sintaxe simplificada para 
criação de coleções e literais para membros da classe.
Considerações finais
Utilizar o Guava e o LambdaJ pode trazer diversos 
ganhos a sua aplicação. Mas será que o código é mais 
expressivo? Possui mais abstração? É mais conciso? 
São critérios de difícil definição e há bastante dis-
cussão a respeito. Deixamos links na referência sobre 
esse assunto.
Mesmo que seu código esteja agora mais expres-
sivo, será que essas novas bibliotecas não serão uma 
barreira grande para novos programadores da equi-
pe? É certamente um ponto que deve ser considerado 
ao adotar APIs como essas. Assim como o impacto de 
performance que o LambdaJ pode trazer por causa do 
uso de muitas dynamic proxies, esses são trade-offs 
que devem ser estudados.
E quando começar a utilizar o Java 8? Apesar de 
já haver milestones sólidos, a API está mudando bas-
tante, além de que não há IDE nenhuma com suporte 
a nova sintaxe. É provável que, no início do ano de 
2013, tanto Eclipse quanto Netbeans ofereçam su-
porte.
Para baixar os builds do JDK8:
> http://openjdk.java.net/projects/jdk8/
> http://openjdk.java.net/projects/lambda/
Para ver a evolução do lambda no JDK8, conheça sua 
antiga sintaxe e propostas:
> http://blog.caelum.com.br/trabalhando-com-closures-
no-java-8/
> http://www.javac.info/
Para conhecer mais do LambdaJ:
> http://blog.caelum.com.br/codigo-expressivo-e-
programacao-funcional-em-java-com-lambdaj
> http://code.google.com/p/lambdaj/wiki/LambdajFeatures
DSLs, interfaces fluentes e outros patterns envolvidos aqui:
> http://martinfowler.com/dsl.html
> http://martinfowler.com/bliki/FluentInterface.html
> http://blog.jayway.com/2012/02/07/builder-pattern-
with-a-twist/
Conhecendo mais do Guava:
> http://code.google.com/p/guava-libraries/
Expressividade, abstração e concisão:
> http://www.joelonsoftware.com/items/2006/08/01.html
> http://gafter.blogspot.com.br/2007/03/on-expressive-
power-of-programming.html
Um pouco de teoria sobre o cálculo lambda e programação 
funcional:
> http://steve.vinoski.net/pdf/IC-Welcome_to_the_
Functional_Web.pdf
> http://blog.caelum.com.br/comecando-com-o-calculo-
lambda-e-a-programacao-funcional-de-verdade/
/referências
Geraldo Ferraz | guilherme.ferraz@caelum.com.br
Analista desenvolvedor da Cast e ministra cursos na Caelum Brasília.
No projeto em que trabalho, chegamos no ponto em que melhorar legibilidade e expressividade tor-
nou-se uma prioridade. Por muito tempo o projeto permaneceu com muitos loops e estruturas de condi-
ções encadeadas, e por mais que extraíssemos métodos não conseguíamos ler o código e saber de primei-
ra o que estava sendo feito. Com o LambdaJ conseguimos melhorar todos os aspectos citados, entretanto, 
adicionamos bastante complexidade e alta dependência da API. Com alguma refatoração é possível dei-
xar o código de forma que a complexidade fique encapsulada tornando o uso muito mais intuitivo.
/eu uso

Outros materiais