SlideShare uma empresa Scribd logo
1 de 24
Baixar para ler offline
12Programação Funcional
Helder da Rocha
helder@argonavis.com.br
Conteúdo
1.Introdução
2.Sintaxe
3.Expressões
4.Arrays e Strings
5.Classes
6.Interfaces
7.Exceções
2
8.Objetos
9.Coleções
10.Datas
11.Threads
12.Programação funcional
13.Arquivos e I/O
14.Bancos de dados
Expressões lambda
• Uma expressão lambda é uma função anônima
• É abstração de uma operação, tratada como se fosse dados,
permitindo que seja atribuída a variáveis e retornada/passada
de/para métodos
• Tem origem no cálculo lambda (Alonzo Church, 1936) e é
usado em programação desde Lisp (1958)
• Faz parte de várias linguagens populares: JavaScript, Scala, C#,
Go, Swift, Smalltalk, Python
3
Programação funcional
• Lambdas são uma abstração fundamental em linguagens
funcionais
• Em orientação a objetos, o estado de objetos é modificado por
operações representadas por seus métodos
• Na programação funcional, operações são representadas por
funções entre objetos imutáveis
• Embora não tenha sido concebida como linguagem funcional, é
possível programar em Java usando o paradigma funcional
• AAPI de streams facilita a programação funcional em Java 8
4
Métodos anônimos em Java
• Desde Java 1.1 pode-se implementar interfaces anônimas
Runnable tarefa = new Runnable() {
@Override
public void run() {
System.out.println("Hello!");
}
}
• Java 8 vai mais longe com métodos anônimos (lambdas)
Runnable tarefa = () -> { System.out.println("Hello!"); }
• As chaves são opcionais neste caso:
Runnable tarefa = () -> System.out.println("Hello!");
5
Sintaxe de expressões lambda
• Novo operador -> (seta) separa parâmetros e expressão
• Variáveis usadas no bloco da expressão lambda devem ser efetivamente
finais (imutáveis)
• Parenteses: obrigatórios se há mais de um parâmetro ou nenhum:
• p -> p/2; // mesmo que (p) -> p/2
• () -> 3; // parênteses necessários
• (a,b) -> a+b; // parênteses necessários
• Declarar tipo dos parâmetros é opcional (se for possível inferir)
• int r = p -> p/2; // Implícito: (int p) -> p/2;
• Chaves e a instrução return: opcionais se apenas uma instrução
int r = (a,b) -> a+b; // (int a, int b) -> { return a+b;}
6
Referências de métodos
• O operador :: declara referências para métodos e construtores
• Há quatro tipos
• Classe::metodoEstatico // referência para metodo estatico
• Classe::metodoDeInstancia // ref. para método de um objeto qualquer
• objeto::metodoDeInstancia // ref. para método de um objeto específico
• Classe::new // referência para construtor
• Exemplos
• System.out::println Comparator::compare
HashSet<Integer>::new
• Uma referência pode substituir uma expressão lambda; os argumentos são
obtidos por inferência (as duas formas abaixo são equivalentes)
Consumer<String> f1 = s -> System.out.println(s);
Consumer<String> f2 = System.out::println;
7
interface Consumer<T> {
void accept(T t);
}
Usará	parâmetro	T	do	
método	por	inferência
Interfaces funcionais
• Interface funcional: interface com um método abstrato
• Se houver outros métodos devem ser static ou default
• Podem ser implementadas usando expressões lambda!
• Java 8 introduziu a anotação @FunctionalInterface para identificar
interfaces funcionais em tempo de compilação
• Haverá erro de compilação se interface não for funcional
• O uso de interfaces funcionais em lambdas permite alto grau de
reuso: lambdas ignoram tipos recebidos/retornados
• O pacote java.util.function contém uma coleção de interfaces padrão
para reuso
8
java.util.function
• 43 interfaces genéricas de propósito geral
• Principais interfaces
• Predicate<T>: Recebe (T); Retorna boolean
• BiPredicate<T,U>: Recebe (T,U); Retorna boolean
• Consumer<T>: Recebe (T); Retorna void
• Supplier<T>: Recebe (); Retorna T
• Function<T,R>: Recebe (T); Retorna R
• BiFunction<T,U,R>: Recebe (T,U); Retorna R
• UnaryOperator<T>: Recebe (T); Retorna T
• BinaryOperator<T, T>: Recebe (T, T); Retorna T
9
Uso de interfaces funcionais
• O nome do método da interface funcional é irrelevante para criar
expressões lambda, já que é anônimo; tipos também são irrelevantes
• O mais importante são: quantidade de argumentos recebidos e
se retorna ou não algum valor
• Uma expressão usando Supplier<T> com T = String
• Uma expressão usando Function<Integer,String>
• Uma expressão usando BiFunction<T, U, R>
10
String produto = () -> "Hello!";
String resultado = (a,b) -> a + b; // concatena ou soma
Integer tamanho = s -> s.length(); // recebe String, retorna Integer
Métodos que recebem lambdas
• Um método que recebe uma expressão lambda declara
receber uma interface funcional
• Pode-se implementar uma função anônima e passá-la como
argumento, da mesma forma como são passados os dados
11
public Integer calcular(Function<Integer> funcao,
Integer operando) {
return funcao.apply(operando);
}
System.out.println( calcular( n -> n * n, 4);
System.out.println( calcular( n -> n / 2, 16);
Streams
• A classe java.util.stream.Stream fornece uma API para
programação funcional baseado na concatenação de operações
lazy processadas quando uma operação terminal é chamada
• Um Stream conduz elementos de uma fonte através de uma pipeline
de operações, produzindo um resultado sem modificar a fonte
• Elementos são processados uma única vez (o stream é consumido)
• Streams podem ser infinitos (operações intermediárias podem limitar
os dados durante o processamento)
• Streams podem ser criados/obtidos de várias formas
12
Como criar um Stream
• Pode ser criado a partir de métodos de fábrica: generate(), iterate(), of(), etc.
Stream<String> letras = Stream.of("X", "T", "S", "P");
Stream<Integer> infinito = 

Stream.generate(()-> new Random().nextInt(100));
• É mais comum criar um stream a partir de uma coleção usando o método
stream() ou parallelStream()
List<Integer> colecao = new ArrayList(); // ...
Stream<Integer> colecao.stream();
Stream<Integer> colecao.parallelStream(); // paralelismo
• Um stream pode ser transformado via operações intermediárias (lazy) e
uma operação terminal (eager - que encerra o stream)
13
Operações de um stream
• As operações intermediárias (lazy) são executadas apenas depois que o
stream é terminado (puxando os dados: método "pull")
• Após uma operação terminal o stream não pode ser reusado
• As operações recebem interfaces funcionais
• Algumas operações. Operações intermediárias retornam Stream:
• filter(Predicate<T>): intermediária
• map(Function<T,U>): intermediária
• flatMap(Function<T,Stream<R>>): intermediária
• reduce(BinaryOperator<T>): terminal
• forEach(Consumer<T>): terminal
• collect(Collector<T,A,R>): terminal
14
Outras	operações	terminais:	
min(),	max(),	count(),	etc.	
Outras	intermediárias:	
skip(),	peek(),	distinct(),	etc.
Filter
• A operação intermediária filter(Predicate<T>) remove do
stream elementos que não combinam com a função
15
List<Integer> numbers =
Arrays.asList(new Integer[] {4,1,9,6,8,3,5});
numbers.stream()
.filter(n -> n > 5)
.forEach(System.out::println);
Imprime	9	
6	
8
Map
• A operação intermediária map(Function<T,U>) recebe
uma função que realiza uma transformação no stream (e
pode converter um tipo em outro):
16
List<Integer> numbers =
Arrays.asList(new Integer[] {4,1,9,6,8,3,5});
numbers.stream()
.filter(n -> n > 5)
.map(n -> n * n)
.forEach(System.out::println);
Imprime	81	
36	
64
ForEach
• O método forEach(Consumer<T>) foi adicionado em Iterable
e está disponível para qualquer implementação (ex: Collection):
list.forEach(System.out::println);
• Stream também implementa Iterable e pode chamar forEach():
Stream<Integer> numeros = Stream.of(1,2,3,4);
numeros.map(s->s*2).forEach(System.out::println);
• ForEach é uma operação terminal (depois de chamada, puxa a
execução do stream não permitindo novos métodos):
numeros.filter(n->n<3); // exceção (stream encerrado)
17
Reduce
• reduce(BinaryOperator<T>) é uma operação terminal que retorna
resultado da operação de combinação sobre valores acumulados
• Há três diferentes versões de reduce (com 1, 2 ou 3 args)
• O resultado pode ser do mesmo tipo (T), outro tipo ou
Optional<T> (objeto que encapsula T ou null)
18
List<Integer> numbers =
Arrays.asList(new Integer[] {4,1,9,6,8,3,5});
Optional<Integer> resultado = numbers.stream()
.filter(n -> n > 5)
.map(n -> n * n)
.reduce((acum, oper) -> a+b);
int soma = resultado.get(); // 181 (81+36+64)
(veja	também	as	outras	duas	formas	de	implementar	reduce())
faz	o	mesmo	que	sum()
Collect
• collect(Collector<T,A,R>) é uma operação terminal que executa
uma redução mutável nos elementos do stream. O coletor constrói
o resultado usando funções de acumulação e combinação.
• collect() pode ser usado para reduzir um stream a uma coleção
• Classe utilitária Collectors contém vários algoritmos
implementados (toList(), groupingBy(), etc.)
19
Map<String, List<Movie>> directors = movieList.stream()
.collect(Collectors.groupingBy(Movie::getDirector));
List<String> titles = movieList
.stream().map(movie -> movie.getTitle()
+ " (" + movie.getDirector()+ ")")
.collect(Collectors.toList());
FlatMap
• flatMap(Function<T,Stream<R>>) é uma operação
intermediária que "achata" um stream de streams
20
List<String> titlesAndDirectors =
movieList.stream()
.flatMap(movie ->
Stream.of(movie.getTitle(),
movie.getDirector()))
.collect(Collectors.toList());
Exceções e valores nulos
• Streams não podem deixar escapar exceções checadas
• É preciso capturar a exceção
• Pode-se lançar uma exceção de runtime
• Ideal é devolver um objeto comum que contenha informações que
permitam lidar com o problema
• Objetos Optional podem ser usados para lidar com valores nulos
21
public Optional<Integer> transformar(Integer valor) {
try {
// operações sobre valor
return Optional.of(resultado);
} catch (Excecao e) {
return Optional.empty();
}
} int valor = 123;
Optional<Integer> op = transformar(valor);
Integer resultado = op.orElse(valor);
Retorna	resultado	ou	
123	(se	ocorrer	exceção	
e	Optional	estiver	vazio)
Streams de primitivos
• java.util.stream também contém um conjunto de Streams de primitivos
como DoubleStream, IntStream e LongStream
• Streams comuns podem ser convertidos em streams de primitivos:
mapToInt(), mapToDouble(), etc.
IntStream stream = lista.stream().mapToInt(n->n);
• Possuem métodos especiais para manipular de primitivos e obter estatísticas
22
IntSummaryStatistics example =
Stream.of(9,4,8,2,15,82,91,77,53,27,13)
.mapToInt(n->n).summaryStatistics();
System.out.printf("Count: %d, Max: %d, Min: %d, Avg: %f, Sum: %d",
example.getCount(), example.getMax(), example.getMin(),
example.getAverage(), example.getSum());
Exercícios
• 1. A classe Movies possui uma lista de objetos Movie que pode ser
obtida com o método getMovies(). Escreva código usando streams que:
• Conte a quantidade de filmes existentes
• Conte a quantidade de filmes de "Stanley Kubrick"
• Obtenha uma lista de filmes com duração menor que 100 minutos
• Obtenha um mapa contendo diretores (String) e uma lista de seus
filmes (Movie)
• Descubra qual o filme mais longo, e o mais curto
• Coloque os filmes em ordem cronológica
• 2. Refatore os exercícios do capítulo 9 para usar Streams (use streams,
lambda e referências de métodos) onde for possível.
• 3. Implemente a função min() usando reduce()
• 4. Transforme a lista de filmes em uma tabela HTML (String)
23
JAVA 8
Helder da Rocha
helder@argonavis.com.br
para programadores
02/02/2015

Mais conteúdo relacionado

Mais procurados

Threads 04 Variáveis atômicas
Threads 04 Variáveis atômicasThreads 04 Variáveis atômicas
Threads 04 Variáveis atômicasHelder da Rocha
 
Collections Api - Java
Collections Api - JavaCollections Api - Java
Collections Api - JavaDrishti Bhalla
 
Spring boot introduction
Spring boot introductionSpring boot introduction
Spring boot introductionRasheed Waraich
 
PUC SE Day 2019 - SpringBoot
PUC SE Day 2019 - SpringBootPUC SE Day 2019 - SpringBoot
PUC SE Day 2019 - SpringBootJosué Neis
 
Junções e subconsultas
Junções e subconsultasJunções e subconsultas
Junções e subconsultasjulianaveregue
 
Java 8 presentation
Java 8 presentationJava 8 presentation
Java 8 presentationVan Huong
 
Java Collections | Collections Framework in Java | Java Tutorial For Beginner...
Java Collections | Collections Framework in Java | Java Tutorial For Beginner...Java Collections | Collections Framework in Java | Java Tutorial For Beginner...
Java Collections | Collections Framework in Java | Java Tutorial For Beginner...Edureka!
 
[Curso Java Basico] Exercicios Aulas 36 a 43
[Curso Java Basico] Exercicios Aulas 36 a 43[Curso Java Basico] Exercicios Aulas 36 a 43
[Curso Java Basico] Exercicios Aulas 36 a 43Loiane Groner
 
Introdução ao Spring Framework
Introdução ao Spring FrameworkIntrodução ao Spring Framework
Introdução ao Spring FrameworkNatanael Fonseca
 
Java orientação a objetos (associacao, composicao, agregacao)
Java   orientação a objetos (associacao, composicao, agregacao)Java   orientação a objetos (associacao, composicao, agregacao)
Java orientação a objetos (associacao, composicao, agregacao)Armando Daniel
 
Angular - Chapter 3 - Components
Angular - Chapter 3 - ComponentsAngular - Chapter 3 - Components
Angular - Chapter 3 - ComponentsWebStackAcademy
 

Mais procurados (20)

Threads 04 Variáveis atômicas
Threads 04 Variáveis atômicasThreads 04 Variáveis atômicas
Threads 04 Variáveis atômicas
 
Java 8 Lambda Expressions
Java 8 Lambda ExpressionsJava 8 Lambda Expressions
Java 8 Lambda Expressions
 
Major Java 8 features
Major Java 8 featuresMajor Java 8 features
Major Java 8 features
 
07 java collection
07 java collection07 java collection
07 java collection
 
Collections Api - Java
Collections Api - JavaCollections Api - Java
Collections Api - Java
 
Java 8 streams
Java 8 streamsJava 8 streams
Java 8 streams
 
Spring boot introduction
Spring boot introductionSpring boot introduction
Spring boot introduction
 
PUC SE Day 2019 - SpringBoot
PUC SE Day 2019 - SpringBootPUC SE Day 2019 - SpringBoot
PUC SE Day 2019 - SpringBoot
 
Spring Core
Spring CoreSpring Core
Spring Core
 
Junções e subconsultas
Junções e subconsultasJunções e subconsultas
Junções e subconsultas
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Java 8 lambda
Java 8 lambdaJava 8 lambda
Java 8 lambda
 
Java 8 presentation
Java 8 presentationJava 8 presentation
Java 8 presentation
 
Java Collections | Collections Framework in Java | Java Tutorial For Beginner...
Java Collections | Collections Framework in Java | Java Tutorial For Beginner...Java Collections | Collections Framework in Java | Java Tutorial For Beginner...
Java Collections | Collections Framework in Java | Java Tutorial For Beginner...
 
[Curso Java Basico] Exercicios Aulas 36 a 43
[Curso Java Basico] Exercicios Aulas 36 a 43[Curso Java Basico] Exercicios Aulas 36 a 43
[Curso Java Basico] Exercicios Aulas 36 a 43
 
Introdução ao Spring Framework
Introdução ao Spring FrameworkIntrodução ao Spring Framework
Introdução ao Spring Framework
 
React + Redux for Web Developers
React + Redux for Web DevelopersReact + Redux for Web Developers
React + Redux for Web Developers
 
Java orientação a objetos (associacao, composicao, agregacao)
Java   orientação a objetos (associacao, composicao, agregacao)Java   orientação a objetos (associacao, composicao, agregacao)
Java orientação a objetos (associacao, composicao, agregacao)
 
Angular - Chapter 3 - Components
Angular - Chapter 3 - ComponentsAngular - Chapter 3 - Components
Angular - Chapter 3 - Components
 
Spring jdbc
Spring jdbcSpring jdbc
Spring jdbc
 

Semelhante a Programação funcional Java

Semelhante a Programação funcional Java (20)

Atualização Java 8 (2014)
Atualização Java 8 (2014)Atualização Java 8 (2014)
Atualização Java 8 (2014)
 
Java 8 - New Features
Java 8 - New FeaturesJava 8 - New Features
Java 8 - New Features
 
Java Is Back, Novidade do Java 8
Java Is Back, Novidade do Java 8Java Is Back, Novidade do Java 8
Java Is Back, Novidade do Java 8
 
Funções e procedimentos
Funções e procedimentosFunções e procedimentos
Funções e procedimentos
 
Programação funcional
Programação funcionalProgramação funcional
Programação funcional
 
Introdução ao paradigma funcional com scala
Introdução ao paradigma funcional com scalaIntrodução ao paradigma funcional com scala
Introdução ao paradigma funcional com scala
 
Lógica de programação pascal
Lógica de programação   pascalLógica de programação   pascal
Lógica de programação pascal
 
Java8
Java8Java8
Java8
 
RevisãoCompactaFuncoesPonteiro.pptx
RevisãoCompactaFuncoesPonteiro.pptxRevisãoCompactaFuncoesPonteiro.pptx
RevisãoCompactaFuncoesPonteiro.pptx
 
Estrutura de dados
Estrutura de dadosEstrutura de dados
Estrutura de dados
 
Apostila estrutura de dados 2
Apostila estrutura de dados 2Apostila estrutura de dados 2
Apostila estrutura de dados 2
 
Ed1
Ed1Ed1
Ed1
 
Python para quem sabe Python (aula 2)
Python para quem sabe Python (aula 2)Python para quem sabe Python (aula 2)
Python para quem sabe Python (aula 2)
 
Linguagem_C.pdf
Linguagem_C.pdfLinguagem_C.pdf
Linguagem_C.pdf
 
Funções em C
Funções em CFunções em C
Funções em C
 
Python Emsl2009
Python Emsl2009Python Emsl2009
Python Emsl2009
 
Introdução+à+linguagem+c
Introdução+à+linguagem+cIntrodução+à+linguagem+c
Introdução+à+linguagem+c
 
Aula 6 pc - slides
Aula 6   pc - slidesAula 6   pc - slides
Aula 6 pc - slides
 
Linguagem C - Ponteiros
Linguagem C - PonteirosLinguagem C - Ponteiros
Linguagem C - Ponteiros
 
07-lambda.pdf
07-lambda.pdf07-lambda.pdf
07-lambda.pdf
 

Mais de Helder da Rocha

Como criar um mapa temático interativo com dados abertos e D3.js
Como criar um mapa temático interativo com dados abertos e D3.jsComo criar um mapa temático interativo com dados abertos e D3.js
Como criar um mapa temático interativo com dados abertos e D3.jsHelder da Rocha
 
Transforming public data into thematic maps (TDC2019 presentation)
Transforming public data into thematic maps (TDC2019 presentation)Transforming public data into thematic maps (TDC2019 presentation)
Transforming public data into thematic maps (TDC2019 presentation)Helder da Rocha
 
TDC 2019: transformando 
dados
públicos
em mapas interativos
TDC 2019: transformando 
dados
públicos
em mapas interativosTDC 2019: transformando 
dados
públicos
em mapas interativos
TDC 2019: transformando 
dados
públicos
em mapas interativosHelder da Rocha
 
Padrões essenciais de mensageria para integração de sistemas
Padrões essenciais de mensageria para integração de sistemasPadrões essenciais de mensageria para integração de sistemas
Padrões essenciais de mensageria para integração de sistemasHelder da Rocha
 
Visualização de dados e a Web
Visualização de dados e a WebVisualização de dados e a Web
Visualização de dados e a WebHelder da Rocha
 
Eletrônica Criativa: criando circuitos com materiais alternativos
Eletrônica Criativa: criando circuitos com materiais alternativosEletrônica Criativa: criando circuitos com materiais alternativos
Eletrônica Criativa: criando circuitos com materiais alternativosHelder da Rocha
 
Introdução à Visualização de Dados (2015)
Introdução à Visualização de Dados (2015)Introdução à Visualização de Dados (2015)
Introdução à Visualização de Dados (2015)Helder da Rocha
 
API de segurança do Java EE 8
API de segurança do Java EE 8API de segurança do Java EE 8
API de segurança do Java EE 8Helder da Rocha
 
Curso de Java Persistence API (JPA) (Java EE 7)
Curso de Java Persistence API (JPA) (Java EE 7)Curso de Java Persistence API (JPA) (Java EE 7)
Curso de Java Persistence API (JPA) (Java EE 7)Helder da Rocha
 
Curso de Enterprise JavaBeans (EJB) (JavaEE 7)
Curso de Enterprise JavaBeans (EJB) (JavaEE 7)Curso de Enterprise JavaBeans (EJB) (JavaEE 7)
Curso de Enterprise JavaBeans (EJB) (JavaEE 7)Helder da Rocha
 
Introdução a JPA (2010)
Introdução a JPA (2010)Introdução a JPA (2010)
Introdução a JPA (2010)Helder da Rocha
 
Curso de RESTful WebServices em Java com JAX-RS (Java EE 7)
Curso de RESTful WebServices em Java com JAX-RS (Java EE 7)Curso de RESTful WebServices em Java com JAX-RS (Java EE 7)
Curso de RESTful WebServices em Java com JAX-RS (Java EE 7)Helder da Rocha
 
Minicurso de Segurança em Java EE 7
Minicurso de Segurança em Java EE 7Minicurso de Segurança em Java EE 7
Minicurso de Segurança em Java EE 7Helder da Rocha
 
Curso de WebServlets (Java EE 7)
Curso de WebServlets (Java EE 7)Curso de WebServlets (Java EE 7)
Curso de WebServlets (Java EE 7)Helder da Rocha
 
Threads 07: Sincronizadores
Threads 07: SincronizadoresThreads 07: Sincronizadores
Threads 07: SincronizadoresHelder da Rocha
 
Threads 08: Executores e Futures
Threads 08: Executores e FuturesThreads 08: Executores e Futures
Threads 08: Executores e FuturesHelder da Rocha
 
Threads 05: Travas de Exclusão Mútua
Threads 05: Travas de Exclusão MútuaThreads 05: Travas de Exclusão Mútua
Threads 05: Travas de Exclusão MútuaHelder da Rocha
 

Mais de Helder da Rocha (20)

Como criar um mapa temático interativo com dados abertos e D3.js
Como criar um mapa temático interativo com dados abertos e D3.jsComo criar um mapa temático interativo com dados abertos e D3.js
Como criar um mapa temático interativo com dados abertos e D3.js
 
Transforming public data into thematic maps (TDC2019 presentation)
Transforming public data into thematic maps (TDC2019 presentation)Transforming public data into thematic maps (TDC2019 presentation)
Transforming public data into thematic maps (TDC2019 presentation)
 
TDC 2019: transformando 
dados
públicos
em mapas interativos
TDC 2019: transformando 
dados
públicos
em mapas interativosTDC 2019: transformando 
dados
públicos
em mapas interativos
TDC 2019: transformando 
dados
públicos
em mapas interativos
 
Padrões essenciais de mensageria para integração de sistemas
Padrões essenciais de mensageria para integração de sistemasPadrões essenciais de mensageria para integração de sistemas
Padrões essenciais de mensageria para integração de sistemas
 
Visualização de dados e a Web
Visualização de dados e a WebVisualização de dados e a Web
Visualização de dados e a Web
 
Eletrônica Criativa: criando circuitos com materiais alternativos
Eletrônica Criativa: criando circuitos com materiais alternativosEletrônica Criativa: criando circuitos com materiais alternativos
Eletrônica Criativa: criando circuitos com materiais alternativos
 
Introdução à Visualização de Dados (2015)
Introdução à Visualização de Dados (2015)Introdução à Visualização de Dados (2015)
Introdução à Visualização de Dados (2015)
 
API de segurança do Java EE 8
API de segurança do Java EE 8API de segurança do Java EE 8
API de segurança do Java EE 8
 
Java 9, 10, 11
Java 9, 10, 11Java 9, 10, 11
Java 9, 10, 11
 
Curso de Java Persistence API (JPA) (Java EE 7)
Curso de Java Persistence API (JPA) (Java EE 7)Curso de Java Persistence API (JPA) (Java EE 7)
Curso de Java Persistence API (JPA) (Java EE 7)
 
Curso de Enterprise JavaBeans (EJB) (JavaEE 7)
Curso de Enterprise JavaBeans (EJB) (JavaEE 7)Curso de Enterprise JavaBeans (EJB) (JavaEE 7)
Curso de Enterprise JavaBeans (EJB) (JavaEE 7)
 
Introdução a JPA (2010)
Introdução a JPA (2010)Introdução a JPA (2010)
Introdução a JPA (2010)
 
Curso de RESTful WebServices em Java com JAX-RS (Java EE 7)
Curso de RESTful WebServices em Java com JAX-RS (Java EE 7)Curso de RESTful WebServices em Java com JAX-RS (Java EE 7)
Curso de RESTful WebServices em Java com JAX-RS (Java EE 7)
 
Minicurso de Segurança em Java EE 7
Minicurso de Segurança em Java EE 7Minicurso de Segurança em Java EE 7
Minicurso de Segurança em Java EE 7
 
Curso de WebServlets (Java EE 7)
Curso de WebServlets (Java EE 7)Curso de WebServlets (Java EE 7)
Curso de WebServlets (Java EE 7)
 
Curso de Java: Threads
Curso de Java: ThreadsCurso de Java: Threads
Curso de Java: Threads
 
Threads 07: Sincronizadores
Threads 07: SincronizadoresThreads 07: Sincronizadores
Threads 07: Sincronizadores
 
Threads 09: Paralelismo
Threads 09: ParalelismoThreads 09: Paralelismo
Threads 09: Paralelismo
 
Threads 08: Executores e Futures
Threads 08: Executores e FuturesThreads 08: Executores e Futures
Threads 08: Executores e Futures
 
Threads 05: Travas de Exclusão Mútua
Threads 05: Travas de Exclusão MútuaThreads 05: Travas de Exclusão Mútua
Threads 05: Travas de Exclusão Mútua
 

Programação funcional Java

  • 1. 12Programação Funcional Helder da Rocha helder@argonavis.com.br
  • 3. Expressões lambda • Uma expressão lambda é uma função anônima • É abstração de uma operação, tratada como se fosse dados, permitindo que seja atribuída a variáveis e retornada/passada de/para métodos • Tem origem no cálculo lambda (Alonzo Church, 1936) e é usado em programação desde Lisp (1958) • Faz parte de várias linguagens populares: JavaScript, Scala, C#, Go, Swift, Smalltalk, Python 3
  • 4. Programação funcional • Lambdas são uma abstração fundamental em linguagens funcionais • Em orientação a objetos, o estado de objetos é modificado por operações representadas por seus métodos • Na programação funcional, operações são representadas por funções entre objetos imutáveis • Embora não tenha sido concebida como linguagem funcional, é possível programar em Java usando o paradigma funcional • AAPI de streams facilita a programação funcional em Java 8 4
  • 5. Métodos anônimos em Java • Desde Java 1.1 pode-se implementar interfaces anônimas Runnable tarefa = new Runnable() { @Override public void run() { System.out.println("Hello!"); } } • Java 8 vai mais longe com métodos anônimos (lambdas) Runnable tarefa = () -> { System.out.println("Hello!"); } • As chaves são opcionais neste caso: Runnable tarefa = () -> System.out.println("Hello!"); 5
  • 6. Sintaxe de expressões lambda • Novo operador -> (seta) separa parâmetros e expressão • Variáveis usadas no bloco da expressão lambda devem ser efetivamente finais (imutáveis) • Parenteses: obrigatórios se há mais de um parâmetro ou nenhum: • p -> p/2; // mesmo que (p) -> p/2 • () -> 3; // parênteses necessários • (a,b) -> a+b; // parênteses necessários • Declarar tipo dos parâmetros é opcional (se for possível inferir) • int r = p -> p/2; // Implícito: (int p) -> p/2; • Chaves e a instrução return: opcionais se apenas uma instrução int r = (a,b) -> a+b; // (int a, int b) -> { return a+b;} 6
  • 7. Referências de métodos • O operador :: declara referências para métodos e construtores • Há quatro tipos • Classe::metodoEstatico // referência para metodo estatico • Classe::metodoDeInstancia // ref. para método de um objeto qualquer • objeto::metodoDeInstancia // ref. para método de um objeto específico • Classe::new // referência para construtor • Exemplos • System.out::println Comparator::compare HashSet<Integer>::new • Uma referência pode substituir uma expressão lambda; os argumentos são obtidos por inferência (as duas formas abaixo são equivalentes) Consumer<String> f1 = s -> System.out.println(s); Consumer<String> f2 = System.out::println; 7 interface Consumer<T> { void accept(T t); } Usará parâmetro T do método por inferência
  • 8. Interfaces funcionais • Interface funcional: interface com um método abstrato • Se houver outros métodos devem ser static ou default • Podem ser implementadas usando expressões lambda! • Java 8 introduziu a anotação @FunctionalInterface para identificar interfaces funcionais em tempo de compilação • Haverá erro de compilação se interface não for funcional • O uso de interfaces funcionais em lambdas permite alto grau de reuso: lambdas ignoram tipos recebidos/retornados • O pacote java.util.function contém uma coleção de interfaces padrão para reuso 8
  • 9. java.util.function • 43 interfaces genéricas de propósito geral • Principais interfaces • Predicate<T>: Recebe (T); Retorna boolean • BiPredicate<T,U>: Recebe (T,U); Retorna boolean • Consumer<T>: Recebe (T); Retorna void • Supplier<T>: Recebe (); Retorna T • Function<T,R>: Recebe (T); Retorna R • BiFunction<T,U,R>: Recebe (T,U); Retorna R • UnaryOperator<T>: Recebe (T); Retorna T • BinaryOperator<T, T>: Recebe (T, T); Retorna T 9
  • 10. Uso de interfaces funcionais • O nome do método da interface funcional é irrelevante para criar expressões lambda, já que é anônimo; tipos também são irrelevantes • O mais importante são: quantidade de argumentos recebidos e se retorna ou não algum valor • Uma expressão usando Supplier<T> com T = String • Uma expressão usando Function<Integer,String> • Uma expressão usando BiFunction<T, U, R> 10 String produto = () -> "Hello!"; String resultado = (a,b) -> a + b; // concatena ou soma Integer tamanho = s -> s.length(); // recebe String, retorna Integer
  • 11. Métodos que recebem lambdas • Um método que recebe uma expressão lambda declara receber uma interface funcional • Pode-se implementar uma função anônima e passá-la como argumento, da mesma forma como são passados os dados 11 public Integer calcular(Function<Integer> funcao, Integer operando) { return funcao.apply(operando); } System.out.println( calcular( n -> n * n, 4); System.out.println( calcular( n -> n / 2, 16);
  • 12. Streams • A classe java.util.stream.Stream fornece uma API para programação funcional baseado na concatenação de operações lazy processadas quando uma operação terminal é chamada • Um Stream conduz elementos de uma fonte através de uma pipeline de operações, produzindo um resultado sem modificar a fonte • Elementos são processados uma única vez (o stream é consumido) • Streams podem ser infinitos (operações intermediárias podem limitar os dados durante o processamento) • Streams podem ser criados/obtidos de várias formas 12
  • 13. Como criar um Stream • Pode ser criado a partir de métodos de fábrica: generate(), iterate(), of(), etc. Stream<String> letras = Stream.of("X", "T", "S", "P"); Stream<Integer> infinito = 
 Stream.generate(()-> new Random().nextInt(100)); • É mais comum criar um stream a partir de uma coleção usando o método stream() ou parallelStream() List<Integer> colecao = new ArrayList(); // ... Stream<Integer> colecao.stream(); Stream<Integer> colecao.parallelStream(); // paralelismo • Um stream pode ser transformado via operações intermediárias (lazy) e uma operação terminal (eager - que encerra o stream) 13
  • 14. Operações de um stream • As operações intermediárias (lazy) são executadas apenas depois que o stream é terminado (puxando os dados: método "pull") • Após uma operação terminal o stream não pode ser reusado • As operações recebem interfaces funcionais • Algumas operações. Operações intermediárias retornam Stream: • filter(Predicate<T>): intermediária • map(Function<T,U>): intermediária • flatMap(Function<T,Stream<R>>): intermediária • reduce(BinaryOperator<T>): terminal • forEach(Consumer<T>): terminal • collect(Collector<T,A,R>): terminal 14 Outras operações terminais: min(), max(), count(), etc. Outras intermediárias: skip(), peek(), distinct(), etc.
  • 15. Filter • A operação intermediária filter(Predicate<T>) remove do stream elementos que não combinam com a função 15 List<Integer> numbers = Arrays.asList(new Integer[] {4,1,9,6,8,3,5}); numbers.stream() .filter(n -> n > 5) .forEach(System.out::println); Imprime 9 6 8
  • 16. Map • A operação intermediária map(Function<T,U>) recebe uma função que realiza uma transformação no stream (e pode converter um tipo em outro): 16 List<Integer> numbers = Arrays.asList(new Integer[] {4,1,9,6,8,3,5}); numbers.stream() .filter(n -> n > 5) .map(n -> n * n) .forEach(System.out::println); Imprime 81 36 64
  • 17. ForEach • O método forEach(Consumer<T>) foi adicionado em Iterable e está disponível para qualquer implementação (ex: Collection): list.forEach(System.out::println); • Stream também implementa Iterable e pode chamar forEach(): Stream<Integer> numeros = Stream.of(1,2,3,4); numeros.map(s->s*2).forEach(System.out::println); • ForEach é uma operação terminal (depois de chamada, puxa a execução do stream não permitindo novos métodos): numeros.filter(n->n<3); // exceção (stream encerrado) 17
  • 18. Reduce • reduce(BinaryOperator<T>) é uma operação terminal que retorna resultado da operação de combinação sobre valores acumulados • Há três diferentes versões de reduce (com 1, 2 ou 3 args) • O resultado pode ser do mesmo tipo (T), outro tipo ou Optional<T> (objeto que encapsula T ou null) 18 List<Integer> numbers = Arrays.asList(new Integer[] {4,1,9,6,8,3,5}); Optional<Integer> resultado = numbers.stream() .filter(n -> n > 5) .map(n -> n * n) .reduce((acum, oper) -> a+b); int soma = resultado.get(); // 181 (81+36+64) (veja também as outras duas formas de implementar reduce()) faz o mesmo que sum()
  • 19. Collect • collect(Collector<T,A,R>) é uma operação terminal que executa uma redução mutável nos elementos do stream. O coletor constrói o resultado usando funções de acumulação e combinação. • collect() pode ser usado para reduzir um stream a uma coleção • Classe utilitária Collectors contém vários algoritmos implementados (toList(), groupingBy(), etc.) 19 Map<String, List<Movie>> directors = movieList.stream() .collect(Collectors.groupingBy(Movie::getDirector)); List<String> titles = movieList .stream().map(movie -> movie.getTitle() + " (" + movie.getDirector()+ ")") .collect(Collectors.toList());
  • 20. FlatMap • flatMap(Function<T,Stream<R>>) é uma operação intermediária que "achata" um stream de streams 20 List<String> titlesAndDirectors = movieList.stream() .flatMap(movie -> Stream.of(movie.getTitle(), movie.getDirector())) .collect(Collectors.toList());
  • 21. Exceções e valores nulos • Streams não podem deixar escapar exceções checadas • É preciso capturar a exceção • Pode-se lançar uma exceção de runtime • Ideal é devolver um objeto comum que contenha informações que permitam lidar com o problema • Objetos Optional podem ser usados para lidar com valores nulos 21 public Optional<Integer> transformar(Integer valor) { try { // operações sobre valor return Optional.of(resultado); } catch (Excecao e) { return Optional.empty(); } } int valor = 123; Optional<Integer> op = transformar(valor); Integer resultado = op.orElse(valor); Retorna resultado ou 123 (se ocorrer exceção e Optional estiver vazio)
  • 22. Streams de primitivos • java.util.stream também contém um conjunto de Streams de primitivos como DoubleStream, IntStream e LongStream • Streams comuns podem ser convertidos em streams de primitivos: mapToInt(), mapToDouble(), etc. IntStream stream = lista.stream().mapToInt(n->n); • Possuem métodos especiais para manipular de primitivos e obter estatísticas 22 IntSummaryStatistics example = Stream.of(9,4,8,2,15,82,91,77,53,27,13) .mapToInt(n->n).summaryStatistics(); System.out.printf("Count: %d, Max: %d, Min: %d, Avg: %f, Sum: %d", example.getCount(), example.getMax(), example.getMin(), example.getAverage(), example.getSum());
  • 23. Exercícios • 1. A classe Movies possui uma lista de objetos Movie que pode ser obtida com o método getMovies(). Escreva código usando streams que: • Conte a quantidade de filmes existentes • Conte a quantidade de filmes de "Stanley Kubrick" • Obtenha uma lista de filmes com duração menor que 100 minutos • Obtenha um mapa contendo diretores (String) e uma lista de seus filmes (Movie) • Descubra qual o filme mais longo, e o mais curto • Coloque os filmes em ordem cronológica • 2. Refatore os exercícios do capítulo 9 para usar Streams (use streams, lambda e referências de métodos) onde for possível. • 3. Implemente a função min() usando reduce() • 4. Transforme a lista de filmes em uma tabela HTML (String) 23
  • 24. JAVA 8 Helder da Rocha helder@argonavis.com.br para programadores 02/02/2015