Docsity
Docsity

Prepare-se para as provas
Prepare-se para as provas

Estude fácil! Tem muito documento disponível na Docsity


Ganhe pontos para baixar
Ganhe pontos para baixar

Ganhe pontos ajudando outros esrudantes ou compre um plano Premium


Guias e Dicas
Guias e Dicas


Utilização de Interfaces Funcionais em Java, Manuais, Projetos, Pesquisas de Informática

Como utilizar interfaces funcionais em java, como consumer, predicate e comparator, para simplificar a manipulação de objetos e coleções. Também aborda a utilização de métodos estáticos e de referência de métodos em interfaces funcionais.

Tipologia: Manuais, Projetos, Pesquisas

2021

Compartilhado em 21/06/2021

edmarssouzap
edmarssouzap 🇧🇷

1 documento

1 / 137

Toggle sidebar

Esta página não é visível na pré-visualização

Não perca as partes importantes!

bg1
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20
pf21
pf22
pf23
pf24
pf25
pf26
pf27
pf28
pf29
pf2a
pf2b
pf2c
pf2d
pf2e
pf2f
pf30
pf31
pf32
pf33
pf34
pf35
pf36
pf37
pf38
pf39
pf3a
pf3b
pf3c
pf3d
pf3e
pf3f
pf40
pf41
pf42
pf43
pf44
pf45
pf46
pf47
pf48
pf49
pf4a
pf4b
pf4c
pf4d
pf4e
pf4f
pf50
pf51
pf52
pf53
pf54
pf55
pf56
pf57
pf58
pf59
pf5a
pf5b
pf5c
pf5d
pf5e
pf5f
pf60
pf61
pf62
pf63
pf64

Pré-visualização parcial do texto

Baixe Utilização de Interfaces Funcionais em Java e outras Manuais, Projetos, Pesquisas em PDF para Informática, somente na Docsity!

Casa do Código

“À família Alexandre Vulcano”

  • Paulo Silveira

“À minha amada esposa”

  • Rodrigo Turini

i

Casa do Código

Agradecimentos

Foi um desafio escrever um livro durante seis meses em que o JDK8 final ainda não existia. Fica um agradecimento a todos que nos ajudaram com dúvidas, sugestões e par- ticipações na lista. Alberto Souza, Francisco Sokol, Guilherme Silveira, Michael Nas- cimento e Osvaldo Duoderlein são alguns deles. Agradecimento especial a Alexan- dre Aquiles, pelas correções e sugestões importantes durante a detalhada revisão. Um muito obrigado a todos os desenvolvedores do JDK8, que em muitas vezes responderam nossas dúvidas prontamente. Destaque para o Brian Goetz, líder do projeto Lambda e sempre muito solícito. Um abraço a todos da Caelum, do Alura e da Casa do Código. São equipes que nos incentivam todos os dias a investigar novas tecnologias, paradigmas e bibliote- cas.

iii

  • 1 Java Sumário
    • 1.1 Um balde de água morna?
    • 1.2 Acesse o código desse livro e discuta com a gente!
  • 2 Olá, Lambda!
    • 2.1 Loops da maneira antiga e da maneira nova
    • 2.2 Que entre o Lambda!
  • 3 Interfaces funcionais
    • 3.1 Outro exemplo: listeners
    • 3.2 Sua própria interface funcional
    • 3.3 A anotação @FunctionalInterface
    • 3.4 Indo mais a fundo: primeiros detalhes
  • 4 Default Methods
    • 4.1 O método forEach na interface Iterable
    • 4.2 A interface Consumer não tem só um método!
    • 4.3 Mais um novo método em Collection: removeIf
    • 4.4 Herança múltipla?
  • 5 Ordenando no Java
    • 5.1 Comparators como lambda
    • 5.2 O método List.sort
    • 5.3 Métodos estáticos na interface Comparator
    • 5.4 Conhecendo melhor o Comparator.comparing
    • 5.5 Ordenando por pontos e o autoboxing
  • 6 Method References Sumário Casa do Código
    • 6.1 Tornando todos os usuários moderadores
    • 6.2 Comparando de uma forma ainda mais enxuta
    • 6.3 Compondo comparators
    • 6.4 Referenciando métodos de instância
    • 6.5 Referenciando métodos que recebem argumentos
    • 6.6 Referenciando construtores
    • 6.7 Outros tipos de referências
  • 7 Streams e Collectors
    • 7.1 Tornando moderadores os 10 usuários com mais pontos
    • 7.2 Streams: tornando moderadores os usuários com mais de 100 pontos
    • 7.3 Como obter de volta uma Lista?
    • 7.4 Collectors
    • 7.5 Avançado: por que não há um toList em Stream?
    • 7.6 Liste apenas os pontos de todos os usuários com o map
    • 7.7 IntStream e a família de Streams
    • 7.8 O Optional em java.util
  • 8 Mais operações com Streams
    • 8.1 Ordenando um Stream
    • 8.2 Muitas operações no Stream são lazy!
    • 8.3 Qual é a vantagem dos métodos serem lazy?
    • 8.4 Enxergando a execução do pipeline com peek
    • 8.5 Operações de redução
    • 8.6 Conhecendo mais métodos do Stream
    • 8.7 Streams primitivos e infinitos
    • 8.8 Praticando o que aprendemos com java.nio.file.Files
    • 8.9 FlatMap
  • 9 Mapeando, particionando, agrupando e paralelizando
    • 9.1 Coletores gerando mapas
    • 9.2 groupingBy e partitioningBy
    • 9.3 Executando o pipeline em paralelo
    • 9.4 Operações não determinísticas e ordered streams
  • 10 Chega de Calendar! Nova API de datas Casa do Código Sumário
    • 10.1 A java.time vem do Joda Time
    • 10.2 Trabalhando com datas de forma fluente
    • 10.3 Enums no lugar de constantes
    • 10.4 Formatando com a nova API de datas
    • 10.5 Datas inválidas
    • 10.6 Duração e Período
    • 10.7 Diferenças para o Joda Time
  • 11 Um modelo de pagamentos com Java
    • 11.1 Uma loja de digital goodies
    • 11.2 Ordenando nossos pagamentos
    • 11.3 Reduzindo BigDecimal em somas
    • 11.4 Produtos mais vendidos
    • 11.5 Valores gerados por produto
    • 11.6 Quais são os produtos de cada cliente?
    • 11.7 Qual é nosso cliente mais especial?
    • 11.8 Relatórios com datas
    • 11.9 Sistema de assinaturas
  • 12 Apêndice: mais Java 8 com reflection, JVM, APIs e limitações
    • 12.1 Novos detalhes na linguagem
    • 12.2 Qual é o tipo de uma expressão Lambda?
    • 12.3 Limitações da inferência no lambda
    • 12.4 Fim da Permgen
    • 12.5 Reflection: parameter names
  • 13 Continuando seus estudos
    • 13.1 Como tirar suas dúvidas
    • 13.2 Bibliotecas que já usam ou vão usar Java

Capítulo 1

Java 8

São praticamente 20 anos de Java desde o lançamento de sua primeira versão. Apenas em 2004, com a chegada do Java 5, houve mudanças significativas na linguagem. Em especial generics, enums e anotações. Com a chegada do Java 8, em 2014, isso acontece mais uma vez. Novas possibili- dades surgem com a entrada do lambda e dos method references, além de pequenas mudanças na linguagem. A API de Collections, na qual as interfaces principais são as mesmas desde 1998, recebe um significativo upgrade com a entrada dos Streams e dos métodos default. Tudo isso será extensivamente praticado durante o livro. É hora de programar. Você deve baixar e instalar o Java 8: http://www.oracle.com/technetwork/java/javase/downloads/ E pode acessar seu javadoc aqui: http://download.java.net/jdk8/docs/api/index.html O Eclipse possui suporte para o Java 8 a partir da versão Luna (4.4). O Kepler (4.3) precisa do seguinte update:

1.1. Um balde de água morna? Casa do Código

https://wiki.eclipse.org/JDT/Eclipse_Java_8_Support_For_Kepler O Eclipse ainda possui alguns pequenos bugs para realizar inferências mais com- plicadas. Netbeans e IntelliJ tem suas versões atualizadas para Java 8. Para fixar a sintaxe, você pode optar por realizar os testes e exemplos do livro com um simples editor de texto.

1.1 Um balde de água morna?

Se você está esperando algo tão poderoso quanto em Scala, Clojure e C#, certamente sairá decepcionado. O legado e a idade do Java, além da ausência de value types e reificação nos generics, impedem o uso de algumas estratégias. O time de desenvol- vedores da linguagem tem também grande preocupação em deixar a sintaxe sempre simples, evitando formas obscuras que trariam pequenos ganhos. Na nossa opinião, faz bastante sentido. Ao mesmo tempo é impressionante o que foi possível atingir com o lançamento dessa nova versão. Você vai se surpreender com alguns códigos e abordagens utiliza- das. O foco é não quebrar a compatibilidade do código antigo e ser o menos intrusivo possível nas antigas APIs. Os Streams, que serão vistos quase que a exaustão, cer- tamente têm um papel crucial nessa elegante evolução.

O que ficou de fora do Java 8?

Para quebrar melhor a especificação do Java 8 em tarefas menores, foram criadas as JEPs: JDK Enhancement Proposals. É uma ideia que nasceu dos PEPs, proposta similar da comunidade Python. A JEP 0 é uma lista com todas essas propostas: http://openjdk.java.net/jeps/ Como você pode ver, são muitas as novidades no JDK8. Infelizmente nem todas tiveram tempo suficiente para amadurecer. Entre as JEPs propostas, os Value Objects ficaram de fora: http://openjdk.java.net/jeps/ Assim como o uso de literais para trabalhar com coleções: http://openjdk.java.net/jeps/ Entre outras ideias que ficaram de fora, temos diversas melhorias aos Garbage Collectors já embutidos, assim como a possível reificação dos generics. De qualquer maneira, a maioria absoluta das JEPs sobreviveu até o lançamento da versão final. Veremos as principais mudanças da linguagem, assim como as novas APIs, no decorrer do livro.

2

Capítulo 2

Olá, Lambda!

Em vez de começar com uma boa dose de teoria, é importante que você sinta na prática como o Java 8 vai mudar a forma com que você programa.

2.1 Loops da maneira antiga e da maneira nova

É importante que você acompanhe o livro recriando o código daqui. Só assim a sintaxe tornar-se-á natural e mais próxima de você. Abra seu editor preferido. Vamos criar uma entidade para poder rodar exemplos baseados nela. Teremos a classe Usuario, com três atributos básicos: pontos, nome e um boolean moderador, indicando se aquele usuário é um moderador do nosso sistema. Simples assim:

class Usuario { private String nome; private int pontos; private boolean moderador;

Casa do Código Capítulo 2. Olá, Lambda!

} } }

Omitimos dois imports: do java.util.List e do java.util.Arrays. Du- rante o livro, eles não vão aparecer, mas notaremos sempre que aparecerem novos pacotes do Java 8. Arrays.asList é uma maneira simples de criar uma List imutável. Mas você poderia sim ter criado uma nova ArrayList e adicionado cada um dos usuários. O for que fazemos é trivial. Desde o Java 5, podemos navegar assim em qual- quer array ou coleção (na verdade, em qualquer tipo de objeto que implemente a interface java.lang.Iterable).

Um novo método em todas as coleções: forEach

A partir do Java 8 temos acesso a um novo método nessa nossa lista: o forEach. De onde ele vem? Veremos mais adiante. Iniciaremos por utilizá-lo. Podemos fazer algo como:

usuarios.forEach(...);

Para cada usuário, o que ele deve fazer? Imprimir o nome. Mas qual é o argu- mento que esse método forEach recebe? Ele recebe um objeto do tipo java.util.function.Consumer, que tem um único método, o accept. Ela é uma nova interface do Java 8, assim como todo o pacote do java.util.function, que conheceremos no decorrer do livro. Vamos criar esse consumidor, antes de usar o novo forEach:

class Mostrador implements Consumer { public void accept(Usuario u) { System.out.println(u.getNome()); } }

Criamos uma classe que implementa essa nova interface do Java 8. Ela é bem trivial, possuindo o único método accept responsável por pegar um objeto do tipo Usuario e consumi-lo. ‘Consumir’ aqui é realizar alguma tarefa que faça sentido pra você. No nosso caso, é mostrar o nome do usuário na saída padrão. Depois disso, podemos instanciar essa classe e passar a referência para o esperado método forEach:

7

2.2. Que entre o Lambda! Casa do Código

Mostrador mostrador = new Mostrador(); usuarios.forEach(mostrador);

Sabemos que é uma prática comum utilizar classes anônimas para essas tarefas mais simples. Em vez de criar uma classe Mostrador só pra isso, podemos fazer tudo de uma tacada só:

Consumer mostrador = new Consumer() { public void accept(Usuario u) { System.out.println(u.getNome()); } };

usuarios.forEach(mostrador);

Isso vai acabar gerando um .class com nome estranho, como por exem- plo Capitulo2$1.class. Como não podemos nos referenciar a um nome dessa classe, chamamo-la de classe anônima, como já deve ser de seu conhecimento. O código ainda está grande. Parece que o for de maneira antiga era mais su- cinto. Podemos reduzir um pouco mais esse código, evitando a criação da variável local mostrador:

usuarios.forEach(new Consumer() { public void accept(Usuario u) { System.out.println(u.getNome()); } });

Pronto! Um pouco mais enxuto, mas ainda assim bastante verboso.

2.2 Que entre o Lambda!

Simplificando bastante, um lambda no Java é uma maneira mais simples de imple- mentar uma interface que só tem um único método. No nosso caso, a interface Consumer é uma boa candidata. Isto é, em vez de escrever:

Consumer mostrador = new Consumer() { public void accept(Usuario u) { System.out.println(u.getNome()); } };

8

2.2. Que entre o Lambda! Casa do Código

usuarios.forEach(u -> u.tornaModerador());

Vale lembrar que essa variável u não pode ter sido declarada no mesmo escopo da invocação do forEach, pois o lambda pode capturar as variáveis de fora, como veremos mais adiante. No próximo capítulo vamos trabalhar mais com lambda, para exercitar a sin- taxe, além de conhecer outros cenários básicos de seu uso junto com o conceito de interface funcional.

Capítulo 3

Interfaces funcionais

Repare que a interface Consumer, por exemplo, tem apenas um único método abstrato, o accept. É por isso que, quando faço o forEach a seguir, o compilador sabe exatamente qual método deverá ser implementado com o corpo do meu lambda:

usuarios.forEach(u -> System.out.println(u.getNome()));

Mas e se a interface Consumer tivesse dois métodos? O fato de essa interface ter apenas um método não foi uma coincidência, mas sim um requisito para que o compilador consiga traduzi-la para uma expressão lambda. Podemos dizer então que toda interface do Java que possui apenas um método abstrato pode ser instanciada como um código lambda! Isso vale até mesmo para as interfaces antigas, pré-Java 8, como por exemplo o Runnable:

public interface Runnable { public abstract void run(); }