Vous êtes sur la page 1sur 7

_lambda

Chegando ao

Lambda
no Java 8
Como melhorar seu cdigo atual (e futuro)
utilizando funes Lambda.
Voc sabe ordenar uma lista? Sabe selecionar os elementos de uma
lista a partir de um critrio? E extrair os valores de uma determinada propriedade do objeto de uma lista?
So 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 adicionam um sabor funcional ao Java atual. Depois chegaremos ao
futuro Java 8, para ver como o lambda e os defender methods esto
mudando a linguagem em direo ao funcional.
Paulo Silveira | paulo.silveira@caelum.com.br
Bacharel e mestre em computao pela Universidade de So Paulo. Fundador do GUJ.com.br, trabalha com Java h 11 anos. um
dos responsveis tcnicos pelos cursos da Caelum.

Raphael Lacerda | raphael.lacerda@caelum.com.br


Ps-graduado em Engenharia de Sistemas. Atua como analista de sistemas no Banco do Brasil e ministra cursos na Caelum Braslia. Entusiasta por expressividade de cdigo e DSLs. Possui as certificaes SCJP e SCWCD. um dos responsveis tcnicos pelos
cursos da Caelum.

37 \

rogramao funcional um tema em alta mesmo


no mercado corporativo. Sua ascenso ficou bem
apresentada pelo artigo de Steve Vinosky, Welcome
to the functional web, e pode ser claramente vista pela grande quantidade de linguagens funcionais
(ou ao menos com um pouco mais de caractersticas
funcionais) na JVM. Scala e Clojure so expoentes
aqui. Os artigos na MundoJ revelam tambm essa
tendncia.
Java orientada a objetos. O que poderamos
aproveitar do conceito do paradigma funcional para
melhorar alguns pontos subjetivos do nosso cdigo:
legibilidade, expressividade e conciso? Usando apenas a API padro, muito pouco. Ficamos refns das
longas e verborrgicas classes annimas, ou de laos que se repetem exaustivamente.
Como o Java e o JCP esto reagindo a essa tendncia? Certamente a linguagem est bastante defasada, no s em relao s outras com pequena
penetrao no mercado corporativo, como Scala e
Clojure, mas tambm do Ruby e Python, sem contar
o C#, que j possui recursos funcionais muito avanados h bastante tempo.
Para a oitava edio da plataforma, prevista para
setembro de 2013, teremos a incluso de uma sintaxe prpria para definir lambdas, em estilo muito
similar a essas linguagens. Veremos, neste artigo,
como ser essa nova sintaxe, junto com algumas novidades da JSR 335.
Mas precisamos esperar ainda um ano para tirar
proveito de uma API mais elaborada, alm da sintaxe
adocicada?
Ao final deste artigo voc conhecer duas bibliotecas funcionais: Guava e LambdaJ. Elas possuem
uma robusta API para facilitar o trabalho do dia a
dia, em especial relacionado a colees. O LambdaJ
vai alm: abusa das proxies dinmicas para mimetizar uma sintaxe diferente.
Voc pode ler este artigo de maneira relativamente independente: mostraremos cada uma das
abordagens para resolver problemas parecidos, envolvendo simples manipulaes de colees, utilizando a classe Palestrante. A Listagem 1 mostra essa
classe, que implementa Comparable de forma trivial
e possui, como atributos, o nmero de posts do palestrante no GUJ, um id e um nome.

Listagem 1. Implementao 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;

/ 38

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 esterides

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? Escrevemos um foreach:
for (Palestrante p : palestrantes) {
System.out.println(p);
}

Para somar todos seus posts, temos outro simples lao:


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 cdigo tambm
bastante simples:
for (Palestrante p : palestrantes) {
if (p.getPostsNoGuj() > 500)
p.favoritar();
}

Para ordern-los atravs de posts, criamos um


Comparator. Podemos fazer isso em outra classe,
mas comum ficar numa classe annima:
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);

So quatro curtos cdigos que estamos cansados


de escrever no dia a dia. Como eles ficam adicionando um pouco de programao funcional? Ser que
torn-los curtos facilitaria a legibilidade? Melhoraria a forma de pensar?

Google Guava

O Guava um apanhado geral de funcionalidades


que os desenvolvedores do Google usam nos projetos
Java da empresa. A biblioteca abrange vrias reas
como colees (inclusive criando outros tipos de collections como o MultiSet), concorrncia, I/O, reflection, validao, dentre outros. Eles resolveram juntar
todos esses utilitrios em um projeto s, dando origem ao Guava. Est disponvel para quem faz gerenciamento de dependncias com o Maven, Gradle, Ivy
e Buildr e tem uma boa documentao.
A prpria biblioteca diz que para tentar atingir
uma programao funcional utilizando Java 7 s
atravs de um cdigo estranho e muito verboso, basicamente utilizando classes annimas, portanto ela
traz funcionalidades para reverter esse quadro.
O projeto contm algumas classes e interfaces
que ajudam na programao no estilo funcional como
Function, Predicate, FluentIterable e uma classe utilitria Collections2. Em suma, podemos fazer uma
operao bsica como filtragem com praticamente
uma combinao de todas elas, o que muda que, por
exemplo, a classe FluentIterable prov essa funcionalidade seguindo o padro FluentInterface.
Como primeiro exemplo, a partir de uma lista de
participantes, deve-se obter uma lista dos nomes em
maisculo. Para isso vamos utilizar os mtodos 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();
}
}));

Comparators. Ela possui alguns mtodos utilitrios


para ordenao, como levar em conta valores null,
ordem reversa, ordem lexicogrfica, verificar se a lista
est ordenada, dentre outros. Vamos fazer trs exemplos rpidos de ordenao. Primeiramente ordenar
uma lista desordenada de participantes pela sua ordem 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
referncias para classes annimas que implementam
a interface Comparator.
List<Palestrante> palestrantesNomePosts =
Ordering.from(nomeComparator).compound(
postsComparator).sortedCopy(palestrantes);

Concluindo, a principal vantagem do Guava em


relao API nativa do Java que ele possui alguns
mtodos de suporte mais efetivos, entretanto criar
classes annimas Function e Predicate no muda
muito em quantidade/expressividade de cdigo.

Agora vamos para um problema mais comum. A LambdaJ


LambdaJ uma bibioteca para manipular colepartir de uma lista de palestrantes, obter somente
es
de uma forma mais simples e natural. Foi criada
aqueles que tiveram mais do que 500 posts.
por Mario Fusco e surgiu devido necessidade de enSystem.out.println(FluentIterable.from(palestrantes).filter(
tender melhor uma parte do domnio que lidava com
new Predicate<Palestrante>() {
interaes em colees em um projeto que ele parti@Override
cipava. A biblioteca foi desenhada como sendo uma
public boolean apply(Palestrante palestrante) {
DSL interna para o Java. Segundo Fusco, esse cdigo
return palestrante.getPostsNoGuj() > 500;
era complexo, repetitivo e de difcil leitura. Os desen}
volvedores gastavam mais tempo tentando adivinhar
}));
o que um determinado loop fazia do que escrevendoExtraindo mtodos e utilizando imports estti- -o. E ele afirma: ...cdigos como este so feitos para
o computador ler e no o programador.... Bom, a sicos, conseguimos um cdigo mais sucinto:
tuao parece familiar para voc?
Ela muito fcil de se utilizar, tem uma boa doSystem.out.println(from(palestrantes).filter(
comPostsMaiorQue500()));
cumentao e basta ir ao site do projeto para baix-la, inclusive j possui um jar nico com todas as dePara fazer funes de ordenao, vamos usar a pendncias e est disponvel tambm para quem faz
classe Ordering, que um comparador fluente e pode o gerenciamento com o Maven. Na parte tcnica, ela
ser usado para manipular, estender e fazer uso de faz muito uso de proxy e reflexo, o que a torna mais
39 \

expressiva que as anteriores, todavia um pouco menos eficiente com relao ao desempenho. Recomenda-se verificar na pgina do projeto a sua anlise de
desempenho e a questo toda pode se resumir a um
trade-off, perdendo um pouco no desempenho para
ganhar na expressividade de cdigo. Sua principal
classe a Lambda, que contm uma srie de mtodos
(funes) estticos.
Inicialmente podemos imprimir o nome de todos
os participantes, para isso vamos utilizar a funo
joinFrom.

Podemos fazer um pequeno refactoring para torn-lo mais legvel:


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 soluo usando Java puro, ocupando algumas linhas de cdigo. J com LambdaJ tudo se resolve com apenas uma linha. Para isso vamos utilizar
System.out.println(joinFrom(palestrantes).getName());
o mtodo select para selecionar os participantes e o
mtodo forEach para percorrer essa lista e favoritO import esttico do mtodo joinFrom foi feito -los. Tambm iremos usar o mtodo having e greapara facilitar a leitura. Agora vamos ordenar os par- terThanOrEqualTo, ambos do Hamcrest, uma depenticipantes a partir da quantidade de posts, para isso dncia do LambdaJ.
vamos utilizar o mtodo sort.
List<Palestrante> participantesOrdenadosPorPost =
sort(palestrantes, on(Palestrante.class).
getPostsNoGuj());

forEach(select(palestrantes,having(on(
Palestrante.class).getPostsNoGuj(),
greaterThanOrEqualTo(500)))).favoritar();

Poderia ter sido usado o mtodo and e or para


adicionar outras restries. Agora a leitura ficou fO item de comparao obtido a partir do mtocil, todavia ainda pode ser melhorada, tornar-se mais
do on. Podemos obter uma expressividade melhor ao
expressiva. Vamos extrair a parte de comparao para
extrair a comparao para um mtodo privado.
um mtodo privado e parametrizar o valor a ser comparado.
List<Palestrante> participantesOrdenadosPorPost =
sort(palestrantes, porPostsNoGuj());

A classe Lambda possui mtodo de agregao


como avg, max e min. Exemplo:

forEach(select(palestrantes,
comPostsMaiorQue(500))).favoritar();

O LambdaJ tambm possui uma classe LambdaCollection que segue o padro Fluent Interface assim
como o FluentIterable do Guava. Vamos utiliz-la
no seguinte problema: tendo uma lista de palestras
Agora a partir de uma lista de participantes, va- (considere a nova classe Palestra abaixo), selecionar
mos colocar todos os nomes em maisculo. Primeiro as palestras que tiveram uma votao superior a 100,
vamos extrair o nome dos participantes. Para isso, ento a partir desta selecionar os seus palestrantes
ordenados por quantidade de posts. Para isso vamos
ser usado o mtodo extract.
utilizar os mtodos with, que devolve uma referncia
List<String> nomesDosPalestrantes =
para uma LambdaCollection, retain, que tem funcioextract(palestrantes, on(Palestrante.class).
namento anlogo ao select e o extract que j vimos
getName());
previamente:
int totalDePosts = sumFrom(palestrantes).
getPostsNoGuj();

Com o nome dos participantes, o objetivo agora


coloc-los em letra maiscula. Para isso vamos usar o
mtodo 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();
}});

/ 40

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());

mais programao funcional na MundoJ/


> Na edio nmero 52 da MundoJ, Bruno Kioshita fez uma excelente introduo sobre paradigma funcional, explicando conceitos
como Functions, Predicates, dentre outros. Tambm abordou como fazer o uso da biblioteca Apache Functor, que possui ideias
parecidas com as bibliotecas que sero descritas neste artigo. Por isso, iremos focar essencialmente na prtica de como utilizar funes
em Java, atualmente com bibliotecas externas e futuramente com o Lambda no Java 8.
> J na edio 53, Leandro Moreira fez um artigo de introduo linguagem Clojure, remetendo a alguns conceitos de Programao
Funcional. Nesta mesma edio Hugo Ferreira descreve vrios problemas que podem ser resolvidos com programao Objeto-Funcional
e, por fim, Rafael Ferreira traz o recurso de pattern matching da linguagem funcional Scala.

Novamente, com uma refatorao, temos:

ter sido adicionado. E no Java 8 ele foi, dentro da interface Iterable.


List<Palestrante> palestrantes = with(palestras).
Isso bastante perigoso: evoluir uma interface
retain(comQuantidadeDeVotosMaiorQue(100)).
adicionando novos mtodos quebram classes exisextract(palestrante()).sort(porPostsNoGuj());
tentes que a implementavam! Como o time fez isso,
Por fim, recomendamos olhar nas referncias minimizando os riscos? Eles adicionaram suporte aos
para verificar as outras funcionalidades da biblioteca, extension methods. Se voc olhar o cdigo-fonte da
alguns mtodos como index, group e project podem interface Iterable, encontrar o seguinte mtodo:
resolver problemas de uma forma mais concisa do
void forEach(Block<? super T> block) default {
que a sua atual soluo. Por exemplo, em um cenrio
Iterables.forEach(this, block);
de aplicaes distribudas, em que h a necessidade
}
de se serializar objetos para transferi-los entre JVMs
diferentes, o padro DTO pode ser utilizado. Ento
Agora voc pode criar mtodos em interfaces no
podemos chegar ao seguinte cdigo, caso queiramos Java e colocar uma implementao default, desoinstanciar objetos do tipo DadosPessoais que tam- brigando suas implementadoras de o reescreverem.
bm possuam o atributo nome:
Algo parecido com os mixins do Ruby e com os traits
do Scala, mas ainda sem a possibilidade de conter
List<DadosPessoais> palestrantesParaTransferencia =
atributos no-estticos. A palavra-chave default,
project(palestrantes,DadosPessoais.
dentro de um mtodo de interface, quem faz essa
class,on(Palestrante.class).
mgica e define-o como extension method. Classes
getId(),on(Palestrante.class).getName());
que implementam Iterable no precisaro reescrever
esse mtodo.
H muitas interfaces e classes novas no Java 8 nos
Lambda no Java 8
pacotes lang e util. Iterables, Comparators, MapStreApesar de estar planejado apenas para setembro
am, BiVal/BiValue so apenas algumas delas, alm do
de 2013, voc j pode utilizar milestones do JDK8,
pacote java.util.functions, onde a Block se encontra.
disponveis para os principais sistemas operacionais,
Trabalharemos com elas no nosso dia a dia e vamos
inclusive para o Mac OSX. O time do lambda do JDK
utilizar algumas delas nessa seo.
8 liderado por Brian Goetz, muito conhecido por
seu livro de programao concorrente na plataforma
palestrantes.forEach(p -> { System.out.println(p); });
Java.
Direto ao cdigo. Dada uma List<Palestrante>
Apesar de trazer muitas novidades, um lambda
palestrantes, como imprimir todos eles?
no pode ser criado de qualquer maneira. O cdigo
palestrantes.forEach(new Block<Palestrante>() {
abaixo no compila:

});

public void apply(Palestrante p) {


System.out.println(p);
}

Quem conhece um pouco da API de colees sabe


que no h um mtodo forEach dentro de List, nem
em suas principais superinterfaces: Collection e Iterable. Para esse cdigo funcionar, alm dessa interface Block precisar existir, esse mtodo forEach precisa

Object o = p -> { System.out.println(p); };

Uma expresso lambda precisa sempre ser atribuda/inferida para uma interface/class abstrata que
possui apenas um nico mtodo abstrato (antigamente chamadas de SAM: single abstract method).
A especificao, ainda em andamento, as chamam
agora de functional interfaces. Por exemplo, para um
Runnable, conseguimos inferir um lambda que no
41 \

recebe argumentos:
Runnable r = () -> { System.out.println(); };

Iterable<Integer> posts =
palestrantes.map(Palestrante::getPostsNoGuj);

Dado que temos os inteiros, podemos som-los


Como o compilador sabe que esse contedo vai
para dentro do mtodo run()? Pois o nico mtodo com o reduce (similar ao foldLeft ou inject em outras
abstrato da interface. Assim como o mtodo apply(T linguagens):
o) o nico da interface Block<T>.
Integer total = posts.reduce(0, (total, proximo)
Podemos ir mais adiante. Quando o lambda vai
-> total+proximo);
realizar apenas uma nica invocao de mtodo com
O reduce recebe o valor inicial da conta, para detodos os parmetros recebidos, podemos cri-lo atrapois aplicar, item a item, o lambda dado. Esse lambda
vs de uma referncia para um mtodo:
possui dois parmetros e ser inferido a uma implepalestrantes.forEach(System.out::println);
mentao da nova interface BinaryOperator.
E para filtrar quem tem mais de 500 posts no
Assustador? O compilador vai inferir que o Block
GUJ? Passamos um lambda para ser utilizado como
a ser passado para o forEach vai ser uma invocao
implementao do mtodo test da nova interface
do mtodo println em cima de System.out, passando
Predicate:
o nico parmetro que esse Block pode receber: um
palestrante. Se voc tivesse passado uma referncia
palestrantes.filter(p -> p.getPostsNoGuj() > 500);
para um mtodo que recebe mais de um parmetro, o
compilador no conseguiria inferir o lambda!
Se voc quer invocar o mtodo favoritar em cada
Vale lembrar que isso no um method lite- um desses palestrantes, basta utilizar o forEach que
ral, da mesma forma que temos class literals (como j conhecemos:
String.class, por exemplo). Fazer Method m = System. palestrantes.filter(p -> p.getPostsNoGuj() > 500).
out::println, ou algo semelhante, no compila. Uma
forEach(Palestrante::favoritar);
referncia a um mtodo nada mais que outra forma de escrever um lambda, ento possui as mesmas
Quer finalmente orden-los? Finalmente h o
restries: h necessidade de uma interface funcional mtodo sort na interface list!
envolvida na expresso.
palestrantes.sort((p1, p2) -> . )
Assim como o forEach, h muitos novos extensions methods na interface Iterable, conhecidos dos
Passando seu Comparator como argumento, poprogramadores funcionais: map, reduce, filter, grou- dendo ser inferido por um lambda.
pBy, mapped etc. Para pegar o nmero de posts que
Com esses novos recursos, o cdigo Java se aprocada Palestrante tem no GUJ, fazemos:
xima ao de linguagens como Scala e Ruby. O mesmo
cdigo em Java, Scala e Ruby, sem abusar muito de
Iterable<Integer> posts = palestrantes.map(
outros recursos da linguagem (como o underscore do
p -> p.getPostsNoGuj());
Scala), ficaria:
Nesse caso nem precisamos usar as chaves depois
palestrantes.map(Palestrante::getPostsNoGuj).
dos parmetros. No precisamos utiliz-los quando
reduce(0, (n, x) -> n+x);
o contedo do mtodo uma instruo de return. O palestrantes.map(_.postsNoGuj).fold(0)(n,x => n+x)
mesmo ocorre com os parnteses dos parmetros, palestrantes.map(&:postsNoGuj).inject(0){|n,x| n+x}
que so opcionais no caso de ser apenas um. Em outras palavras, poderamos escrever:
Esse foi apenas um sucinto comeo do que est
por
vir. Vale conhecer todos os mtodos dentro de
Iterable<Integer> posts = palestrantes.map((p)
Iterable,
assim como as interfaces do java.util.func-> { return p.getPostsNoGuj(); } );
tions e as novas superinterfaces das collections. H
Ou ainda podemos usar a notao de method re- ainda references para construtores, novos mtodos
ference:
em classes importantes do Java 8 e pequenas melhorias por toda API. Ser um grande passo para a pla-

/ mais projetos: Apache Collections


> Existe tambm o j conhecido projeto Apache Collections, que possui algumas novas interfaces e classes utilitrias para manipular
colees.

/ 42

/eu uso
Geraldo Ferraz | guilherme.ferraz@caelum.com.br
Analista desenvolvedor da Cast e ministra cursos na Caelum Braslia.

No projeto em que trabalho, chegamos no ponto em que melhorar legibilidade e expressividade tornou-se uma prioridade. Por muito tempo o projeto permaneceu com muitos loops e estruturas de condies encadeadas, e por mais que extrassemos mtodos no conseguamos ler o cdigo e saber de primeira o que estava sendo feito. Com o LambdaJ conseguimos melhorar todos os aspectos citados, entretanto,
adicionamos bastante complexidade e alta dependncia da API. Com alguma refatorao possvel deixar o cdigo de forma que a complexidade fique encapsulada tornando o uso muito mais intuitivo.

/referncias

para saber mais/


> Herana e Composio os princpios por trs dos

Para baixar os builds do JDK8:

padres, ed. 39 da MundoJ Eduardo Guerra

> http://openjdk.java.net/projects/jdk8/

> JPA 2: Os novos recursos inspirados no Hibernate, ed.

> http://openjdk.java.net/projects/lambda/

39 da MundoJ Paulo Silveira e Raphael Lacerda


> Enums desmistificadas, ed. 26 da MundoJ Alexandre
Gazola
> Srie Design patterns para um Mundo Real, eds. 21, 22
e 23 da MundoJ Rodrigo Yoshima

Para ver a evoluo do lambda no JDK8, conhea sua


antiga sintaxe e propostas:
> http://blog.caelum.com.br/trabalhando-com-closuresno-java-8/
> http://www.javac.info/
Para conhecer mais do LambdaJ:
> http://blog.caelum.com.br/codigo-expressivo-eprogramacao-funcional-em-java-com-lambdaj

taforma. Ao mesmo tempo, alguns outros itens ainda ficaram de fora, como a sintaxe simplificada para
criao de colees e literais para membros da classe.

Consideraes finais

Utilizar o Guava e o LambdaJ pode trazer diversos


ganhos a sua aplicao. Mas ser que o cdigo mais
expressivo? Possui mais abstrao? mais conciso?
So critrios de difcil definio e h bastante discusso a respeito. Deixamos links na referncia sobre
esse assunto.
Mesmo que seu cdigo esteja agora mais expressivo, ser que essas novas bibliotecas no sero uma
barreira grande para novos programadores da equipe? 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 so trade-offs
que devem ser estudados.
E quando comear a utilizar o Java 8? Apesar de
j haver milestones slidos, a API est mudando bastante, alm de que no h IDE nenhuma com suporte
a nova sintaxe. provvel que, no incio do ano de
2013, tanto Eclipse quanto Netbeans ofeream suporte.

> 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-patternwith-a-twist/
Conhecendo mais do Guava:
> http://code.google.com/p/guava-libraries/
Expressividade, abstrao e conciso:
> http://www.joelonsoftware.com/items/2006/08/01.html
> http://gafter.blogspot.com.br/2007/03/on-expressivepower-of-programming.html
Um pouco de teoria sobre o clculo lambda e programao
funcional:
> http://steve.vinoski.net/pdf/IC-Welcome_to_the_
Functional_Web.pdf
> http://blog.caelum.com.br/comecando-com-o-calculolambda-e-a-programacao-funcional-de-verdade/

43 \