novidades do java 8
TRANSCRIPT
14/10/2015
2
Uma plataforma de desenvolvimento de software,
Que contém uma linguagem de mesmo nome e
Uma extensa e flexível API.
14/10/2015 (C) 2015, Jandl. 3
20 anos de existência.
8 versões. Linguagem de
programação mais usada da atualidade.
Milhões de downloads do JDK.
14/10/2015 (C) 2015, Jandl. 4
Linguagem OO, Sintaxe simples (C/C++), Fortemente tipada, Independente de
plataforma, Dotada de coleta de lixo, Dinâmica, extensível,
segura, multithreaded e Alto desempenho. Suporta herança simples,
definição de interfaces, reflexão, genéricos e lambdas.
14/10/2015
3
14/10/2015 (C) 2015, Jandl. 5
Versão com o maior número de adições substanciais desde a versão 5:
Métodos de extensão para interfaces
Expressões Lambda
Referências para métodos
Streams e operações em massa para coleções
Nova API DateTime
Paralelização de operações
Anotações melhoradas
14/10/2015 (C) 2015, Jandl. 6
Conteúdo deste minicurso!
14/10/2015
4
14/10/2015 (C) 2015, Jandl. 7
Templo Borobudur, Java, Indonésia.
As interfaces são essenciais dentro do projeto orientado a objetos e o Java 8 traz novas possibilidades para sua evolução.
14/10/2015 8(C) 2015, Jandl.
14/10/2015
5
Conjunto dos elementos visíveis nos objetosde uma classe:
Denomina os atributos e operações expostos paraoutras classes e objetos.
Métodos e campos públicos de um objetoconstituem sua interface.
14/10/2015 (C) 2015, Jandl. 9
14/10/2015 (C) 2015, Jandl. 10
14/10/2015
6
Java (e outras linguagens de programação) oferece uma construção denominadainterface:
Define um conjunto de métodos públicos e abstratos correlacionados.
Pode incluir constantes.
14/10/2015 (C) 2015, Jandl. 11
Interface Reversible Propósito: definir características comuns (uma
interface) para objetos que podem/devem serrepresentados de trás-para-frente.
Operações:▪ getElement(int) - retorna o elemento da posição dada;
▪ isReversed() - retorna true se o elemento está invertido;
▪ length() - retorna o número de elementos presentes;
▪ reverse() – inverte a sequência de elementos do objeto;
▪ toString() – retorna representação textual do objeto.
14/10/2015 (C) 2015, Jandl. 12
14/10/2015
7
Exemplo
package jandl.j8i;
public interface Reversible {char SEPARATOR =',';Object getElement(int p);boolean isReversed();int length();Reversible reverse();String toString();
}
14/10/2015 (C) 2015, Jandl. 13
Métodos são implicitamente public abstract
Campos são implicitamente
public static final
14/10/2015 (C) 2015, Jandl. 14
14/10/2015
8
Por si só, a definição de uma interface nãotem utilidade.
Aplicação efetiva se dá por meio de classes que realizam ou implementam umainterface:
Classe inclui implementação (código) dos métodos definidos na interface realizada(segue o contrato).
Classe pode realizar múltiplas interfaces.
14/10/2015 (C) 2015, Jandl. 15
É como herança múltipla!
Exemplopackage jandl.j8i;
public class ReversibleString implements Reversible {private StringBuilder content;private boolean inverted;
public ReversibleString(String content) {if (content == null) throw new IllegalArgumentException("content==null");this.content = new StringBuilder(content);inverted = false;
}
@Override public Object getElement(int p) { return content.charAt(p); }
public String getText() { return content.toString(); }
@Override public boolean isReversed() { return inverted; }
@Override public int length() { return content.length(); }
@Overridepublic Reversible reverse() {
content.reverse();inverted = !inverted;return this;
}
@Overridepublic String toString() {
StringBuilder sb = new StringBuilder();for(int p=0; p<content.length(); p++) {
sb.append(content.charAt(p));if (p<content.length()-1) sb.append(SEPARATOR);
}return sb.toString();
}}
14/10/2015 (C) 2015, Jandl. 16
Métodos sobrepostos
atendem interface
Elementos adicionais podem
ser incluídos
14/10/2015
9
Classe ReversibleStringrepresenta uma cadeiade caracteres reversível.
Caso não implementetodos os métodos da interface, seráconsiderada uma classeabstrata.
14/10/2015 (C) 2015, Jandl. 17
<interface>Reversible
ReversibleString
Object
Uso:// declaração de objetoReversibleString rs;// instanciaçãors = new ReversibleString(”Java");// exibiçãoSystem.out.println(rs);// reversãors.reverse();// reexibiçãoSystem.out.println(rs.toString());
Polimorfismo:Object o = rs;System.out.println(o.toString())Reversible r = rs;rs.reverse();
14/10/2015 (C) 2015, Jandl. 18
<interface>Reversible
ReversibleString
Object
14/10/2015
10
Muitas classes podem realizar uma mesmainterface.
A interface constitui um elo comum entre taisimplementações.
Classe IntArray é outra possibilidade e representa um arranjo reversível de valoresinteiros que também realiza a interface Reversible.
14/10/2015 (C) 2015, Jandl. 19
Exemplopackage jandl.j8i; public class IntArray implements Reversible {
private int[] value;private boolean inverted;
public IntArray(int tam) { value = new int[tam]; inverted = false;
} public IntArray(int... valor) {
this.value = new int[valor.length]; for (int i = 0; i < valor.length; i++) {
this.value[i] = valor[i]; } inverted = false;
} @Override public Object getElement(int p) { return value[p]; } @Override public boolean isReversed() { return inverted; } @Override public int length() { return value.length; }
@Override public Reversible reverse() {
for (int i = value.length / 2 - 1; i >= 0; i--) { int aux = value[i]; value[i] = value[value.length - 1 - i]; value[value.length - 1 - i] = aux;
} inverted = !inverted; return this;
} public void setValor(int p, int v) { value[p] = v; }
@Override public String toString() { :return sb.toString();
} }
14/10/2015 (C) 2015, Jandl. 20
Métodos sobrepostos
atendem interface
Elementos adicionais podem
ser incluídos
14/10/2015
11
14/10/2015 (C) 2015, Jandl. 21
<interface>Reversible
ReversibleString
Object
IntArray
ReversibleString e IntArray
compartilham de dupla herança.
Exemploimport jandl.j8i.IntArray;import jandl.j8i.Reversible;import jandl.j8i.ReversibleString;
public class Teste {public static void main(String[] args) {
ReversibleString rs = new ReversibleString("Peter Jandl Junior");
testaReversao(rs); IntArray arranjo = new IntArray(20, 15, 8, 30); testaReversao(arranjo); arranjo.reverse();
}
public static void testaReversao(Reversible r) { for(int i=0; i<2; i++) {
System.out.println(r + ":" + r.isReversed()); r.reverse();
} System.out.println(r + ":" + r.isReversed());
} }
14/10/2015 (C) 2015, Jandl. 22
Método pode manipular qualquer objeto que realiza interface indicada
Objetos distintos que realizam
interface Reversible
14/10/2015
12
14/10/2015 (C) 2015, Jandl. 23
Existem circunstâncias onde uma interface deve ser modificada para acompanhar a evolução do projeto.
Estratégia direta é definir uma sub-interface:
Herança permite que interfaces existentes sejam estendidas em sub-interfaces.
Possibilita o reuso das definições existentes e também a adição de novas operações.
14/10/2015 (C) 2015, Jandl. 24
14/10/2015
13
Interface Reversible poderia evoluir como Reversible2:
package jandl.j8i;
public interface Reversible2 extends Reversible {
String toStringUnreversed(Reversible r);
}
14/10/2015 (C) 2015, Jandl. 25
Reversible2 adiciona o método toStringUnreversedàs definições de Reversible
Novas classes podem optar pelaimplementação de Reversible ouReversible2.
Alternativa de criação de sub-interface ésimples e adequada para muitos casos
Mas … Não resolve casos onde se torna necessário
adicionar uma operação em uma interface existente.
14/10/2015 (C) 2015, Jandl. 26
14/10/2015
14
Até Java 7 a adição de novas operações eminterface existente cria problema sério:
Todas as classes que realizam a interface alteradadevem ser modificadas para incluir novasoperações.
Se não forem modificadas, tornam-se abstratas e não podem ser instanciadas.
Nos dois casos ocorre a propagação do problemada interface para classes que a utilizam.
14/10/2015 (C) 2015, Jandl. 27
Java 8 soluciona questão da adição de novasoperações em interfaces existentes por meiodos métodos de extensão:
Métodos Default
Métodos Estáticos
14/10/2015 (C) 2015, Jandl. 28
14/10/2015
15
A partir do Java 8 uma interface pode conteruma ou mais implementações de métodospara definir as novas operações desejadas.
Tais métodos devem ser declarados comodefault.
14/10/2015 (C) 2015, Jandl. 29
Exemplopackage jandl.j8i;
public interface Reversible {char SEPARATOR =',';Object getElement(int p);boolean isReversed();int length();Reversible reverse();String toString();
// Método default (dotado de implementação)default String toStringUnreversed() {
if (isReversed()) { StringBuilder sb = new StringBuilder(); for(int p=length()-1; p>=0; p--) {
sb.append(getElement(p)); if (p>0) sb.append(SEPARATOR);
} return sb.toString();
} else { return toString();
} }
}
14/10/2015 (C) 2015, Jandl. 30
Código pode instanciar e usar objetos, além de
fazer uso de métodos abstratos
da própria interface!
Métodos default também são
implicitamente public
14/10/2015
16
Adição do método defaulttoStringUnreversed() na interface Reversible não implica em qualquermodificação nas classes ReversibleString e IntArray (que realizam Reversible).
Este método default pode ser utilizado porquaisquer objetos destas e de outras classes que realizem a interface Reversible.
14/10/2015 (C) 2015, Jandl. 31
Métodos comuns (ou de instância) sãooperações que podem ser executadasapenas por meio de instâncias (objetos).
Métodos estáticos (ou de classe) podem serexecutados por meio de suas classes, semnecessidade de instâncias, além de seremcompartilhados por todos os objetos de suaclasse.
14/10/2015 (C) 2015, Jandl. 32
14/10/2015
17
A partir do Java 8 as interfaces tambémpodem incluir métodos estáticos.
Todas as classes que realizam tais interfaces passam a compartilhar este métodos.
Métodos estáticos das interfaces podem serexecutados por meio de suas interfaces, semnecessidade de instâncias.
Métodos estáticos só podem utilizar elementosexternos estáticos ou internamente instanciados.
14/10/2015 (C) 2015, Jandl. 33
Exemplo
package jandl.j8i;public interface Reversible {
char SEPARATOR =',';Object getElement(int p);boolean isReversed();int length();Reversible reverse();String toString();
static String toStringUnreversed(Reversible r) {if (r.isReversed()) {
StringBuilder sb = new StringBuilder();for(int p=r.length()-1; p>=0; p--) {
sb.append(r.getElement(p));if (p>0) sb.append(SEPARATOR);
}return sb.toString();
} else {return r.toString();
} }default String toStringUnreversed() {
if (isReversed()) { StringBuilder sb = new StringBuilder(); for(int p=length()-1; p>=0; p--) {
sb.append(getElement(p)); if (p>0) sb.append(SEPARATOR);
} return sb.toString();
} else { return toString();
} } }14/10/2015 (C) 2015, Jandl. 34
Código pode instanciar e usar
objetos, mas apenas acessar
elementos externos estáticos!
Métodos estáticos também são
implicitamente public
São poucas, mas existem diferençasna implementação
de métodos estáticos e default!
14/10/2015
18
Exemploimport jandl.j8i.IntArray;import jandl.j8i.Reversible;import jandl.j8i.ReversibleString;
public class Teste2 {public static void main(String[] args) {
ReversibleString rs = new ReversibleString("Java 8 Interfaces");teste(rs);IntArray ia = new IntArray(31, 35, 64, 68, 95);teste(ia);
}
public static void teste(Reversible r) {r.reverse();System.out.println(r);System.out.println(r.toStringUnreversed());System.out.println(Reversible.toStringUnreversed(r));System.out.println(r);
}}
14/10/2015 (C) 2015, Jandl. 35
Observe as formas de acionamento
dos métodos estáticos e default!
14/10/2015 (C) 2015, Jandl. 36
14/10/2015
19
Os métodos extensão permitem a evoluçãodas interfaces sem a propagação dos problemas usuais decorrentes de suaalteração.
A alteração de interfaces com métodosdefault e estáticos garante compatibilidadebinária com suas versões antigas.
14/10/2015 (C) 2015, Jandl. 37
Java - Guia do Programador. 3ª. Edição.Peter Jandl Junior.Novatec. 2015.
Java -Interfaces.http://www.tutorialspoint.com/java/java_interfaces.htm
What Is an Interface? (The Java Tutorials).https://docs.oracle.com/javase/tutorial/java/concepts/interface.html
14/10/2015 (C) 2015, Jandl. 38
14/10/2015
20
14/10/2015 (C) 2015, Jandl. 39
Monte Gunung & Vulcão Bromo, Java, Indonésia.
A construção mais importante introduzida no Java 8 que incorpora características do paradigma funcional.
14/10/2015 40(C) 2015, Jandl.
14/10/2015
21
Permitem definir métodos anônimosdiretamente no local de sua utilização.
Um método/função-membro anônimosintetiza funcionalidade usada uma única vez.
Evita o uso de classes anônimas.
Na prática torna possível a passagem de código para métodos ao invés de objetos.
14/10/2015 (C) 2015, Jandl. 41
É uma função anônima, i.e., método sem nome, sem especificadores de acesso, sem modificadores, sem indicação do tipo de retorno e dos tipos do parâmetros*.
Declaração privilegia funcionalidade (seu código).
14/10/2015 (C) 2015, Jandl. 42
* Q
uan
do
po
ssível.
14/10/2015
22
Consiste numa lista de parâmetros enviadadiretamente para uma expressão, cujoresultado é retornado implicitamente:
(listaParâmetros) -> expressão
14/10/2015 (C) 2015, Jandl. 43
Lista de parâmetros cujos valores serão
utilizados pela expressão lambda.
Expressão que define operações
realizadas pela expressão lambda.
Novo operador lambda.
Exemplos:
(x) -> 2*x + 1
(x,y) -> 3*x >= 2*y
( ) -> (int)(Math.random()*6) + 1
(a,b) -> a>b ? a : b
(p,m,h) -> 1.5*p + 1.9*m + 2.0*h
14/10/2015 (C) 2015, Jandl. 44
Função que dado o parâmetro x retorna (ou produz) o resultado da expressão 2*x + 1.
Parâmetros p, m, h são enviados para expressão 1.5*p + 1.9*m + 2.0*h retornando seu resultado.
Função sem parâmetros que produz o resultado da expressão
(int)(Math.random()*6+1.
14/10/2015
23
Parêntesis iniciais: São requeridos para delimitar a lista de parâmetros.
Podem ser omitidos quando existe somente um parâmetro.
Tipos dos parâmetros: Podem ser omitidos quando inferidos pelo compilador,
a partir do contexto de uso da expressão lambda.
Quando a inferência de tipos não é possível, devem ser indicados como na declaração de métodos.
Diretiva return: Expressões lambda puras não requerem uso explícito.
Expressões lambda de bloco exigem uso explícito.14/10/2015 (C) 2015, Jandl. 45
Expressões lambda mais sofisticadas podemincluir um bloco de código onde:
Variáveis podem ser declaradas e usadas;
Objetos podem ser instanciados e usados;
São empregadas diretivas e expressões;
Retorno de resultado explícito.
Sintaxe:
(listaParâmetros) -> { bloco_de_código }
14/10/2015 (C) 2015, Jandl. 46
14/10/2015
24
Exemplo
// retorna a soma dos elementos do array entre// as posições sp (incluída) e ep (não incluída).
(double[] array, int sp, int ep) -> {double total = 0;for(int i=sp; i<ep; i++) {
total =+ array[i];}return total;
}
14/10/2015 (C) 2015, Jandl. 47
Os tipos dos parâmetros foram indicados para exemplificar sintaxe. Isto só é requerido quando compilador não
consegue inferir tais tipos.
Expressão lambda constituída de bloco de
código.
Retorno explícito do resultado da
expressão.
14/10/2015 (C) 2015, Jandl. 48
14/10/2015
25
Métodos são descritos por meio de sua assinatura, isto é, combinação de:
Tipo de retorno;
Nome; e
Lista dos tipos dos parâmetros
Expressões lambda são, analogamente, descritas por um target-type ou tipo-alvo com:
Tipo de retorno e
Lista dos tipos dos parâmetros.
14/10/2015 (C) 2015, Jandl. 49
Exemplos de assinaturas de métodos:
Math.pow double pow (double,double)
String.length int length (void)
Long.parseLong long parseLong(String,int)
Exemplo de target-type de lambdas:
(x) -> 2*x + 1 int (int)double (double)
(x,y) -> x >2*y boolean (double,double)
( ) -> Math.PI/2 double (void)
(s) -> s.charAt(2) char (String)14/10/2015 (C) 2015, Jandl. 50
Depende do contexto de uso (do tipo efetivo
do parâmetro x).
14/10/2015
26
Conhecimento dos target-type permite:
Determinar onde lambdas podem ser empregadas.
Orientar a construção de expressões compatíveis com necessidades específicas.
Aplicação de expressões lambda requer conhecimento sobre as interfaces funcionais pré-definidas na API e também como construir novas interfaces funcionais.
14/10/2015 (C) 2015, Jandl. 51
14/10/2015 (C) 2015, Jandl. 52
14/10/2015
27
São aquelas que possuem um único métodoabstrato em suas declarações.
Já existiam antes do Java 8 sob o nomede single abstract methods (SAM) interfaces.
Nova denominação direciona o uso das expressões lambda (construções típicas do paradigma de programação funcional).
14/10/2015 (C) 2015, Jandl. 53
Exemplo
package jandl.j8l;
@FunctionalInterfacepublic interface Filter {
boolean accept(Student s);}
14/10/2015 (C) 2015, Jandl. 54
Nova anotação para designar interface
funcional.
Pode existir qualquer número de métodos de
extensão adicionais.
Apenas um método abstrato pode ser
incluído numa interface funcional.
14/10/2015
28
Interface Filter define um métodoboolean accept (Student)cujo objetivo é validar um objeto do tipo Student, verificando se atende ou não algum critério específico.
Classe Student representa um estudante por meio de seu registro acadêmico, nome e (código do) curso.
14/10/2015 (C) 2015, Jandl. 55
Exemplopackage jandl.j8l;public class Student {// campos para atributos do tipo
private long sId;private String name; private int course;
// construtorpublic Student(long sId, String name, int course) {
this.sId = sId; this.name = name; this.course = course;
} // métodos getter públicos
public long getSID() { return sId; } public String getName() { return name; } public int getCourse() { return course; }
// métodos setter protegidosprotected void setSID(long sId) { this.sId = sId; } protected void setName(String name) { this.name = name; } protected void setCourse(int course) { this.course = course; }
// representação textual@Overridepublic String toString() {
return String.format("[%07d|%03d] %s", sId, course, name); }
}14/10/2015 (C) 2015, Jandl. 56
Classe comum para representar uma
entidade estudante.
14/10/2015
29
Exemplopackage jandl.j8l;import java.util.ArrayList;
public class StudentDB {// campo estático db arraylist que simula banco de dados
public static ArrayList<Student> db = new ArrayList<>();// bloco estático para inicialização do campo estático db
static { db.add(new Student(1200001, "Bernardo Silva", 18)); db.add(new Student(1200015, "Alice Pedrosa Souza", 18)); db.add(new Student(1200348, "Miguel Costa", 18)); db.add(new Student(1300001, "Arthur Santos", 18)); db.add(new Student(1300001, "Julia Oliveira", 116)); : // e outros mais.
}public static ArrayList<Studant> subList(Filter filter) {
// cria sublistaArrayList<Student> result = new ArrayList<>(); // percorre todo banco de dados for(Student s: db) {
// aplica filtro: se critério aceito, adiciona na sublistaif (filter.accept(s)) result.add(s);
} return result; // retorna sublista
} }
14/10/2015 (C) 2015, Jandl. 57
Um falso banco de dados para conter
uma coleção de estudantes.
Método que obtém uma subconjunto de estudantes que
atendem um critério.
A criação de um filtro específico para objetos do tipo Student pode ser feita por meio da construção de uma classe que realize a interface Filter.
Assim, a implementação do métodoboolean accept (Student) pode determinar o critério de filtragem desejado.
14/10/2015 (C) 2015, Jandl. 58
14/10/2015
30
Exemplo
package jandl.j8l;
public class CourseFilterImplimplements Filter {
@Overridepublic boolean accept(Student s) {
// aceita estudantes do curso 18return s.getCourse()==18;
} }
14/10/2015 (C) 2015, Jandl. 59
Classe CourseFilterImpl
realiza interface Filtercom implementação
do método accept.
Método accept aceitaobjetos Student cujo
curso seja 18.
Dispomos de:
Interface funcional Filter;
Classe (entidade) Student;
Classe (banco de dados) StudentDB; e
Classe (filtro específico) CourseFilterImpl.
Com estes elementos é possível testar a filtragem de elementos provida pela classe StudentDB com subList(Filter).
14/10/2015 (C) 2015, Jandl. 60
14/10/2015
31
Exemploimport java.util.ArrayList;
public class Teste01 {public static void main(String[] args) {
System.out.println("Todos:");System.out.println(StudentDB.db.toString());
ArrayList<Student> lista18 = StudentDB.subList( new CourseFilterImpl() );
System.out.println("Curso 18:");System.out.println(lista18.toString());
ArrayList<Student> lista2014 = StudentDB.subList(new Filter () {
@Override public boolean accept(Student s) {
return s.getSID()>1400000; } }
); System.out.println("RA>1400000:");System.out.println(lista2014.toString());
}}
14/10/2015 (C) 2015, Jandl. 61
Obtém sub-lista de estudantes do curso 18, com uso do filtro implementado como classe independente.
Obtém sub-lista de estudantes
ingressantes a partir de 2014, com uso do filtro implementado como
classe anônima.
Programa de teste funciona como operado: Método StudentDB.sublist(Filter) é bastante
conveniente.
Implementação de classe específica/independente para filtro mostra-se repetitiva, além de fragmentar (abstração do) código.
Uso de classe anônima evita fragmentação do código, evidencia critério de filtragem, mas acrescenta complexidade e repetição ao código.
14/10/2015 (C) 2015, Jandl. 62
14/10/2015
32
Exemploimport java.util.ArrayList;
public class Teste02 {public static void main(String[] args) {
System.out.println("Todos:");System.out.println(StudentDB.db.toString());
ArrayList<Student> lista18 = StudentDB.subList( new CourseFilterImpl() );
System.out.println("Curso 18:");System.out.println(lista18.toString());
ArrayList<Student> lista2014 = StudentDB.subList(new Filter () {
@Override public boolean accept(Student s) {
return s.getSID()>1400000; } }
); System.out.println("RA>1400000:");System.out.println(lista2014.toString());
}}
14/10/2015 (C) 2015, Jandl. 63
Método subList requer objeto que realize a
interface Filter.
Requisito é suprido com instância de classe
independente que implementa tal
interface.
Requisito é suprido com instância de classe anônima que realiza tal
interface.
Exemploimport java.util.ArrayList;
public class Teste02 {public static void main(String[] args) {
System.out.println("Todos:");System.out.println(StudentDB.db.toString());
ArrayList<Student> lista18 = StudentDB.subList( s -> s.getCourse() == 18 );
System.out.println("Curso 18:");System.out.println(lista18.toString());
ArrayList<Student> lista2014 = StudentDB.subList(
s -> s.getSID()>1400000;
); System.out.println("RA>1400000:");System.out.println(lista2014.toString());
}}
14/10/2015 (C) 2015, Jandl. 64
Método subList requer objeto que realize a
interface Filter.
Lambda supre código efetivo da interface funcional requerida.
Lambda evidencia a ação desejada sem código burocrático!
14/10/2015
33
14/10/2015 (C) 2015, Jandl. 65
Java 8 inclui novo pacote java.util.functionque contém a definição de muitas interfaces funcionais de propósito geral.
Estas interfaces provêm target-types para expressões lambda e referências de métodos.
Sua existência é mera conveniência, visto que a definição de interfaces é um procedimento simples.
14/10/2015 (C) 2015, Jandl. 66
14/10/2015
34
A 43 interfaces existentes são organizadas em grupos:
Function
Consumer
Supplier
Predicate
Operator
14/10/2015 (C) 2015, Jandl. 67
Consulte:https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html
14/10/2015 (C) 2015, Jandl. 68
14/10/2015
35
14/10/2015 (C) 2015, Jandl. 69
Interface Descrição
Function<T,R> Representa função que toma um argumento e produz um resultado.
BiFunction<T,U,R> Representa função que toma dois argumentos e produz um resultado.
DoubleFunction<R> Representa função que toma um argumento double e produz um resultado.
DoubleToIntFunction Representa função que toma um argumento double e produz um resultado int.
DoubleToLongFunction Representa função que toma um argumento double e produz um resultado long.
IntFunction<R> Representa função que toma um argumento int e produz um resultado.
IntToDoubleFunction Representa função que toma um argumento int e produz um resultado double.
IntToLongFunction Representa função que toma um argumento int e produz um resultado long.
LongFunction<R> Representa função que toma um argumento long e produz um resultado.
LongToDoubleFunction Representa função que toma um argumento long e produz um resultado double.
LongToIntFunction Representa função que toma um argumento long e produz um resultado int.
14/10/2015 (C) 2015, Jandl. 70
Interface Descrição
ToDoubleBiFunction<T,U>Representa função que toma dois argumentos e produz um resultado double.
ToDoubleFunction<T> Representa função que produz um resultado double.
ToIntBiFunction<T,U> Representa função que toma dois argumentos e produz um resultado int.
ToIntFunction<T> Representa função que produz um resultado int.
ToLongBiFunction<T,U> Representa função que toma dois argumentos e produz um resultado long.
ToLongFunction<T> Representa função que produz um resultado long.
14/10/2015
36
14/10/2015 (C) 2015, Jandl. 71
14/10/2015 (C) 2015, Jandl. 72
Interface Descrição
Consumer<T> Representa operação que toma um argumento único de entrada e não retorna resultado.
BiConsumer<T,U> Representa operação que toma dois argumentos de entrada e não retorna resultado.
DoubleConsumer Representa operação que toma um único argumento double e não retorna resultado.
IntConsumer Representa operação que toma um único argumento int e não retorna resultado.
LongConsumer Representa operação que toma um único argumento long e não retorna resultado.
ObjDoubleConsumer<T> Representa operação que toma um argumento objeto e outro double e não retornaresultado.
ObjIntConsumer<T> Representa operação que toma um argumento objeto e outro int, e não retorna resultado.
ObjLongConsumer<T> Representa operação que toma um argumento objeto e outro long, e não retornaresultado.
14/10/2015
37
14/10/2015 (C) 2015, Jandl. 73
14/10/2015 (C) 2015, Jandl. 74
Interface Descrição
Supplier<T> Representa supridor de resultados.
BooleanSupplier Representa supridor de resultado boolean.
DoubleSupplier Representa supridor de resultados double.
IntSupplier Representa supridor de resultados int.
LongSupplier Representa supridor de resultados long.
Supplier<T> Representa supridor de resultados.
BooleanSupplier Representa supridor de resultado boolean.
DoubleSupplier Representa supridor de resultados double.
14/10/2015
38
14/10/2015 (C) 2015, Jandl. 75
14/10/2015 (C) 2015, Jandl. 76
Interface Descrição
Predicate<T> Representa predicado (função boolean) de um argumento.
BiPredicate<T,U> Representa predicado (função boolean) de dois argumentos.
DoublePredicate Representa predicado (função boolean) de um argumento double.
IntPredicate Representa predicado (função boolean) de um argumento int.
LongPredicate Representa predicado (função boolean) de um argumento long.
Predicate<T> Representa predicado (função boolean) de um argumento.
BiPredicate<T,U> Representa predicado (função boolean) de dois argumentos.
DoublePredicate Representa predicado (função boolean) de um argumento double.
14/10/2015
40
14/10/2015 (C) 2015, Jandl. 79
Interface Descrição
UnaryOperator<T> Representa operação sobre um operando produzindo um resultado do mesmo tipo do operando.
BinaryOperator<T> Representa operação sobre dois operandos do mesmo tipo, produzindo um resultado do mesmo tipo dos operandos.
DoubleBinaryOperator Representa operação sobre dois operandos double e produzindo um resultado double.
DoubleUnaryOperator Representa operação sobre um único argumento double que produz um resultado double.
IntBinaryOperator Representa operação sobre dois operandos int e produzindo um resultado int.
IntUnaryOperator Representa operação sobre um único argumento int que produz um resultado int.
LongBinaryOperator Representa operação sobre dois operandos long e produzindo resultado long.
LongUnaryOperator Representa operação sobre um único argumento long que produz um resultado long.
14/10/2015 (C) 2015, Jandl. 80
14/10/2015
41
CLASSE INDEPENDENTE
public class CourseFilterImplimplements Filter {
@Overridepublic boolean accept(Student s) {
return s.getCourse()==18;}
}
EXPRESSÃO LAMBDA
s -> s.getCourse() == 18
14/10/2015 (C) 2015, Jandl. 81
CLASSE ANÔNIMA
new Filter () {@Overridepublic boolean accept(Student s) {
return s.getSID()>1400000;}
}
EXPRESSÃO LAMBDA
s -> s.getSID()>1400000
14/10/2015 (C) 2015, Jandl. 82
14/10/2015
42
Substituem convenientemente o uso de classes independentes e anônimas que realizam interfaces funcionais.
Código claro que explicita operação desejada.
Seu uso é equivale à transferência de código.
Simplifica criação de threads, listeners do tipo ActionListener, comparadores do tipo Comparator<T>, entre outros usos.
14/10/2015 (C) 2015, Jandl. 83
LISTENER CONVENCIONAL
JButton button = newJButton("Incrementar");
button.addActionListener(new ActionListener () {
@Overridepublic void actionListener
(ActionEvent e) {// incr. variável valor do escopovalor++;// imprime valor no consoleSystem.out.println(”V:" + valor);
}});
COM EXPRESSÃO LAMBDA
JButton button = newJButton("Incrementar");
button.addActionListener( (e) -> { // incr. variável valor do escopovalor++;// imprime valor no consoleSystem.out.println(”V:" + valor);
});
14/10/2015 (C) 2015, Jandl. 84
Acesso à variáveis presentes no escopo é denominado captura de variáveis e não provoca efeitos colaterais
(como closures).
14/10/2015
43
THREAD CONVENCIONAL
Runnable run = new Runnable () {@Override
public void run () {for(int i = 0; i<1000000; i++) {
// realiza alguma operaçãodoSomeOperation(i);
}}
};Thread thread = new Thread(run);thread.start();
COM EXPRESSÃO LAMBDA
Runnable run = () -> {for(int i = 0; i<1000000; i++) {
// realiza alguma operaçãodoSomeOperation(i);
}};
Thread thread = new Thread(run);thread.start();
14/10/2015 (C) 2015, Jandl. 85
14/10/2015 (C) 2015, Jandl. 86
14/10/2015
44
Substituem com facilidade e clareza osmétodos abstratos de interfaces funcionaiscom target-type compatíveis.
Código gerado equivale ao de classe anônimaequivalente (não há ganho, não há perda).
Isolamento provido por captura de variáveis éoutro ganho obtido com sua aplicação.
14/10/2015 (C) 2015, Jandl. 87
Java - Guia do Programador. 3ª. Edição.Peter Jandl Junior.Novatec. 2015.
Lambda Expressions (The Java Tutorials).https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
When to Use Nested Classes, Local Classes, Anonymous Classes, and Lambda Expressions(The Java Tutorials).https://docs.oracle.com/javase/tutorial/java/javaOO/whentouse.html
Lambda Expressions in Java 8.http://www.drdobbs.com/jvm/lambda-expressions-in-java-8/240166764
14/10/2015 (C) 2015, Jandl. 88
14/10/2015
45
14/10/2015 (C) 2015, Jandl. 89
Libélula (Dragonfly), Java, Indonésia.
Uma importante construção introduzida no Java 8 juntamente com as expressões lambda.
14/10/2015 90(C) 2015, Jandl.
14/10/2015
46
Uma referência para método é uma indicação de que um método existente em outra classe deve ser utilizado num ponto específico do código.
Este mecanismo também é válido para construtores.
14/10/2015 91(C) 2015, Jandl.
Uso de referência para método requer que target-type do método seja compatível com aquele requerido no local da referência.
Target-type é a combinação das informações relativas ao tipo de retorno da expressão lambda, seguida da lista dos tipos de seus parâmetros entre parêntesis.
Target-type previamente definido por meio de interface funcional.
14/10/2015 92(C) 2015, Jandl.
14/10/2015
47
Compatibilidade exigida entre target-typerequerido e referência para método torna possível:
Utilizar uma referência para método no local onde uma expressão lambda é aceita.
Utilizar uma expressão lambda no local onde uma referência para método é aceita.
Assim: expressões lambda e referências para métodos tem uso intercambiável.
14/10/2015 93(C) 2015, Jandl.
Uso de referências para métodos é útil para evitar a redefinição de métodos existentes em outras classes.
Não interfere na possibilidade de uso de expressões lambda.
14/10/2015 94(C) 2015, Jandl.
14/10/2015
48
Referências para métodos estáticos;
Referências para métodos de instância de objeto específico;
Referências para métodos de instância de objeto arbitrário de tipo; e
Referências para construtores.
14/10/2015 95(C) 2015, Jandl.
14/10/2015 (C) 2015, Jandl. 96
14/10/2015
49
Tipo mais simples de referência para método. Indica um método estático com visibilidade
pública Sintaxe:
NomeClasse::metodoEstatico
▪ NomeClasse nome da classe que contémmétodo estático
▪ metodoEstatico nome do método estático
14/10/2015 (C) 2015, Jandl. 97
Classe java.lang.Math possui vários métodos públicos e estáticos: double cbrt(double)
double exp(double)
double log(double) Compatível com interfaces prédefinidas no
pacote java.util.function: DoubleUnaryOperator
DoubleFunction<T>
Function<T,V>
14/10/2015 (C) 2015, Jandl. 98
Target type é double(double)
14/10/2015
50
Então, as referências para tais métodos poderiam ser declaradas como:
DoubleUnaryOperator f_cbrt = Math::cbrt;
DoubleFunction<Double> f_exp = Math::exp;
Function<Double,Double> f_log = Math::log;
14/10/2015 (C) 2015, Jandl. 99
Função genérica Function<tipoR,tipoP>
cujo target type é: tipoR(tipoP)
Outros métodos da classe java.lang.Math:
double min(double,double)
double max(double,double)
double pow(double,double)
Compatível com interfaces predefinidas no pacote java.util.function:
DoubleBinaryOperator
BinaryOperator<T>
14/10/2015 (C) 2015, Jandl. 100
Target type é double(double,double)
14/10/2015
51
Então, as referências para tais métodos poderiam ser declaradas como:
DoubleBinaryOperator f_max = Math::max;
BinaryOperator<Double> f_min = Math::min;
Calculavel f_pow = Math::pow;
14/10/2015 (C) 2015, Jandl. 101
Toda referência para método possui uma expressão lambda equivalente (de mesmo target-type):
DoubleUnaryOperatorf_cbrt2 = (v) -> Math.cbrt(v);
BinaryOperator<Double>f_min2 = (a, b) -> Math.min(a, b);
14/10/2015 (C) 2015, Jandl. 102
14/10/2015
52
Uso da referência para método exige o acionamento do método declarado pela interface funcional e não do método referenciado:
f_max.applyAsDouble(double, double);
f_cbrt.applyAsDouble(double);
14/10/2015 (C) 2015, Jandl. 103
Método declarado na interface funcional
DoubleUnaryOperator
Método declarado na interface funcional
DoubleBinaryOperator
Exemplo
package jandl.j8r;import java.util.function.*;
public class RefMetEstatico {public static void main(String[] args) {
// Uso direto dos métodos da classe MathSystem.out.println("cbrt(27.0)=" + Math.cbrt(27.0));System.out.println("exp(1.0)=" + Math.exp(1.0));System.out.println("max(2.0, 1.5)=" + Math.max(2.0, 1.5));System.out.println("min(2.0, 1.5)=" + Math.min(2.0, 1.5));
// Referências de métodos com assinatura double (double)DoubleUnaryOperator f_cbrt = Math::cbrt;DoubleFunction<Double> f_exp = Math::exp;
// Referências de métodos com assinatura double (double, double)DoubleBinaryOperator f_max = Math::max;BinaryOperator<Double> f_min = Math::min;
// Uso das referências de métodosSystem.out.println("cbrt(27.0)=" + f_cbrt.applyAsDouble(27.0));System.out.println("exp(1.0)=" + f_exp.apply(1.0));System.out.println("max(2.0, 1.5)=" + f_max.applyAsDouble(2.0, 1.5));System.out.println("min(2.0, 1.5)=" + f_min.apply(2.0, 1.5));
// Expressões lambda equivalentesDoubleUnaryOperator f_cbrt2 = v -> Math.cbrt(v);BinaryOperator<Double> f_min2 = (a, b) -> a < b ? a : b;
// Uso das referências (de métodos) para expressões lambdaSystem.out.println("cbrt2(729)=" + f_cbrt2.applyAsDouble(729));System.out.println("min2(2.0, 1.5)=" + f_min2.apply(2.0, 1.5));
}}14/10/2015 (C) 2015, Jandl. 104
14/10/2015
53
14/10/2015 (C) 2015, Jandl. 105
Indica um método de instância (de um objeto) com visibilidade pública.
Sintaxe:
objeto::metodoInstancia
▪ objeto referência válida (não nula) paraum objeto específico
▪ metodoInstancia nome do método de instância
14/10/2015 (C) 2015, Jandl. 106
14/10/2015
54
Exemplopackage jandl.j8r;
public class Resistor {protected double resistencia;
public Resistor(double resistencia) {setResistencia(resistencia);
}
public double getResistencia() {return resistencia;
}
public void setResistencia(double resistencia) {if (resistencia <= 0) {
throw new RuntimeException("Resistência inválida: " + resistencia);}this.resistencia = resistencia;
}
public double correnteParaTensao(double tensao) {return tensao / resistencia;
}
public double tensaoParaCorrente(double corrente) {return resistencia * corrente;
}
@Overridepublic String toString() {
return String.format("R:%7.1fOhms", resistencia);}
}
14/10/2015 (C) 2015, Jandl. 107
Classe Resistor dispõe de métodos de instância: getResistencia(), setResistencia(double), correnteParaTensao(double) tensaoParaCorrente(double)
Uma instância denominada r10k pode ser obtida com: Resistor r10k = new Resistor(10000);
Seus métodos de instância são referenciados como: r10K::getResistencia r10K::setResistencia r10K::correnteParaTensao r10K::tensaoParaCorrente
14/10/2015 (C) 2015, Jandl. 108
14/10/2015
55
Exemplo
package jandl.j8r;
import java.util.function.DoubleConsumer;import java.util.function.DoubleFunction;import java.util.function.DoubleSupplier;
public class RefMetInstancia {
public static void main(String[] args) {// Instanciação de objeto tipo Resistor
Resistor resistor = new Resistor(10000);System.out.println("Resistência : " + resistor);
// Referências para métodos da instância r10kDoubleSupplier get_resistencia = resistor::getResistencia;DoubleConsumer set_resistencia = resistor::setResistencia;DoubleFunction<Double> i_V = resistor::correnteParaTensao;DoubleFunction<Double> v_I = resistor::tensaoParaCorrente;
// Manipulação da instância via referências para métodosSystem.out.println("Resistência : " + get_resistencia.getAsDouble());System.out.println("i para V=12V: " + i_V.apply(12));System.out.println("v para i=0.001A: " + v_I.apply(0.001));set_resistencia.accept(1000);System.out.println("Nova Resistência : " + resistor);System.out.println("Resistência : " + get_resistencia.getAsDouble());System.out.println("i para V=12V: " + i_V.apply(12));System.out.println("v para i=0.001A: " + v_I.apply(0.001));
}}
14/10/2015 (C) 2015, Jandl. 109
Referências para métodos de instância.
Manipulação da instância por meio de
referências.
Referências para métodos de instância somente afetam o objeto especificamente referenciado.
Estas referências também são equivalentes a expressões lambda: DoubleSupplier
get_resistencia_2 = () -> r10k.getResistencia(); DoubleConsumer
set_resistencia_2 = (r) -> r10k.setResistencia(r); DoubleFunction<Double>
i_V_2 = (v) -> r10k.correnteParaTensao(v); DoubleFunction<Double>
v_I_2 = (i) -> r10k.tensaoParaCorrente(i);
14/10/2015 (C) 2015, Jandl. 110
14/10/2015
56
14/10/2015 (C) 2015, Jandl. 111
Indica um método de instância (de qualquer objeto de um tipo) com visibilidade pública.
Sintaxe:
NomeClasse::metodoInstancia
▪ NomeClasse indica classe que contém métodode instância
▪ metodoInstancia nome do método de instância
14/10/2015 (C) 2015, Jandl. 112
14/10/2015
57
Necessidade de ordenar objetos é comum. Dado array de objetos Resistor:
Resistor[] resistorArray = {new Resistor(1234), new Resistor(23456),new Resistor(345), new Resistor(67),new Resistor(879), new Resistor(1098),new Resistor(543) } ;
Ordenação deste array poderia empregar:
java.util.Arrays.sort (T[], Comparator<T>)
14/10/2015 (C) 2015, Jandl. 113
Solução convencional seria construir uma classe dotada da interface java.util.Comparator<T> para suprir o comparador necessário.
Tal classe deve possuir implementação que contenha o método int compare (T a, T b)destinado à comparar objetos para possibilitar sua ordenação.
14/10/2015 (C) 2015, Jandl. 114
14/10/2015
58
Exemplo
package jandl.j8r;
import java.util.Comparator;
// Comparador específico para objetos Resistorpublic class ResistorComparator
implements Comparator<Resistor> {
@Overridepublic int compare(Resistor a, Resistor b) {
return (int) (a.getResistencia() - b.getResistencia());}
}
14/10/2015 (C) 2015, Jandl. 115
Array resistorArray pode ser ordenado com:
Arrays.sort(resistorArray,new ResistorComparator());
Opção mais simples seria utilizar um lambda para suprir operação de comparação, pois Comparator<T> é uma interface funcional:
Arrays.sort(resistorArray, (Resistor a, Resistor b) —> (int) (a.getResistencia() - b.getResistencia()));
14/10/2015 (C) 2015, Jandl. 116
14/10/2015
59
Outra opção seria incluir um método estático capaz de efetuar a comparação de dois objetos do tipo Resistor na própria classe. public static int comparador(Resistor a, Resistor b) {
return (int) (a.getResistencia() - b.getResistencia());}
Como target-type desse método é o mesmo do lambda usado na ordenação do array int (Resistor, Resistor), é possível ordenar array de tipo Resistorcom: Arrays.sort(resistorArray, Resistor::comparador);
14/10/2015 (C) 2015, Jandl. 117
Ainda outra opção seria um método de instância para efetuar a comparação de dois objetos do tipo Resistor na própria classe.
public int comparador2(Resistor b) {return (int) (this.getResistencia() - b.getResistencia());
}
Embora com assinatura int (Resistor), semântica é a mesma de int (Resistor, Resistor), pois envolve captura de dois objetos Resistor, assim:
Arrays.sort(resistorArray, Resistor::comparador2);
14/10/2015 (C) 2015, Jandl. 118
14/10/2015
60
Exemplo
package jandl.j8r;
import java.util.Arrays;
public class RefMetTipo {public static void main(String[] args) throws Exception {
// Array de resistoresResistor[] resistorArray = { new Resistor(1234), new Resistor(23456),
new Resistor(345), new Resistor(67), new Resistor(879),new Resistor(1098), new Resistor(543) };
Resistor[] copia;System.out.println("0:" + Arrays.toString(resistorArray));// Ordenação do array com comparator específicocopia = resistorArray.clone();Arrays.sort(copia, new ResistorComparator());System.out.println("1:" + Arrays.toString(copia));// Ordenação do array com expressão lambdacopia = resistorArray.clone();Arrays.sort(copia, (Resistor a, Resistor b) -> (int) (a
.getResistencia() - b.getResistencia()));System.out.println("2:" + Arrays.toString(copia));// Ordenação do array com referência para método estáticocopia = resistorArray.clone();Arrays.sort(copia, Resistor::comparador);System.out.println("3:" + Arrays.toString(copia));// Ordenação do array c/ referência para método de instância de tipocopia = resistorArray.clone();Arrays.sort(copia, Resistor::comparador2);System.out.println("4:" + Arrays.toString(copia));
}}
14/10/2015 (C) 2015, Jandl. 119
Referência para método estático.
Referência para método de instância.
14/10/2015 (C) 2015, Jandl. 120
14/10/2015
61
Indica um construtor de com visibilidade pública.
Sintaxe:
NomeClasse::new
▪ NomeClasse indica classe que contémconstrutor
▪ new indica operação de instanciação
Como antes uso da referência para construtor deve ser compatível com interface funcional.
14/10/2015 (C) 2015, Jandl. 121
Exemplo com classe String:
String s1 = "Java";
String s2 = new String("Java");
Fábrica de String com interface Supplier<T>:
public static Supplier<String>StringFactory = String::new;
Uso da fábrica ao invés de instanciação direta:
String s3 = StringFactory.get();
14/10/2015 (C) 2015, Jandl. 122
14/10/2015
62
Exemplopackage jandl.j8r;import java.util.ArrayList;import java.util.List;import java.util.function.Supplier;
public class RefMetConstrutor {// Método fábrica de listas de objetos do tipo Tpublic static <T> List<T> createList() {
return new ArrayList<T>();}
// Supplier de listas<Resistor>public static Supplier<List<Resistor>> resistorListFactory = ArrayList<Resistor>::new;
public static void main(String[] args) throws Exception {// Obtenção explícita de listaList<Long> lista1 = new ArrayList<Long>();// Obtenção de lista com fábrica com inferência de tipoList<Long> lista2 = RefMetConstrutor.createList();// Obtenção de lista com SupplierList<Resistor> lista3 = RefMetConstrutor.resistorListFactory.get();// Uso das listaslista1.add(123456789L);lista1.add(135791113L);lista2.addAll(lista1);lista2.add(2468101214L);lista3.add(new Resistor(10));lista3.add(new Resistor(360));lista3.add(new Resistor(4700));lista3.add(new Resistor(82000));// Exibição das listasSystem.out.println("Lista1: " + lista1); System.out.println("Lista2: " + lista2);System.out.println("Lista3: " + lista3);
}}
14/10/2015 (C) 2015, Jandl. 123
Referência para construtor
O uso da referência para construtor permite alguma simplificação do código necessário, embora o método fábrica genérico seja mais flexível devido à possível parametrização de tipos.
A referência para construtor é, como antes, equivalente a uma expressão lambda:
public static Supplier<List<Long>>listFactory = () -> new ArrayList<Long>();
14/10/2015 (C) 2015, Jandl. 124
14/10/2015
63
14/10/2015 (C) 2015, Jandl. 125
Java 8 tornou possível o uso de referências para métodos existentes no lugar de expressões lambda, desde que suas assinaturas sejam compatíveis.
É uma alternativa interessante que permite substituir o uso de instâncias de classes auxiliares, instâncias de classes anônimas e até mesmo expressões lambda pela indicação de métodos e construtores disponíveis.
Bom uso pode reduzir a quantidade de código necessária, simplificando o desenvolvimento de aplicações.
14/10/2015 (C) 2015, Jandl. 126
14/10/2015
64
Como para as expressões lambda, as substituições possíveis dependem da existência de interfaces funcionais compatíveis.
API do Java 8 contribui com oferta de muitas interfaces funcionais de propósito geral no pacote java.util.function que podem servir de target-type para lambdas e referências de métodos.
14/10/2015 (C) 2015, Jandl. 127
Java - Guia do Programador. 3ª. Edição.Peter Jandl Junior.Novatec. 2015.
Method References (The Java Tutorials).https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html
Java 8 - Lambdas, Method References andComposition.http://www.studytrails.com/java/java8/Java8_Lambdas_FunctionalProgramming.jsp
Java Lambda Expressions vs MethodReferences.https://dzone.com/articles/java-lambda-expressions-vs
14/10/2015 (C) 2015, Jandl. 128
14/10/2015
65
14/10/2015 (C) 2015, Jandl. 129
Templo Prambanan, Java, Indonésia.
Nova funcionalidade do Java 8 que possibilita a realização de operações de filtragem, mapeamento e redução no conteúdo de coleções.
14/10/2015 (C) 2015, Jandl. 130
14/10/2015
66
14/10/2015 (C) 2015, Jandl. 131
Característica da linguagem Java que permite a construção de métodos e tipos genéricos.
Uma classe ou método genérico é capaz de operar com tipos específicos distintos conforme sua parametrização de tipo.
Sua aplicação é flexível e, ainda assim, garante consistência e robustez de suas construções.
14/10/2015 (C) 2015, Jandl. 132
14/10/2015
67
14/10/2015 (C) 2015, Jandl. 133
Grande conjunto de estruturas de dados de propósito geral, na forma de conjunto de classes e interfaces, contidas no pacote java.util.
Utilizam os genéricos extensivamente para permitir sua adaptação aos tipos de dados específicos de cada problema.
14/10/2015 (C) 2015, Jandl. 134
14/10/2015
68
Dentre as interfaces principais destacam-se:
Collection<T>
Set<T>
List<T>
Queue<T>
Map<K,V>
14/10/2015 (C) 2015, Jandl. 135
Dentre as classes (ou implementações) principais destacam-se:
HashSet<T> conjunto
LinkedHashSet<T> conjunto
ArrayList<T> array/lista elástico
LinkedList<T> lista ligada
ArrayQueue<T> array/fila/pilha elástico
HashMap<K,V> mapa/tabela de espalha/o
TreeMap<K,V> árvore
14/10/2015 (C) 2015, Jandl. 136
14/10/2015
69
14/10/2015 (C) 2015, Jandl. 137
Verifica se coleçãocontém elemento
não navegado.
Retorna próximo elemento não
navegado.
Toda e qualquer coleção pode ser navegada com:
// obtém Iterator a partir da coleçãoIterator it = colecao.iterator(); // laço percorre e exibe elementos da coleçãowhile (it.hasNext()) {
System.out.println("Elemento: " + it.next());}
A navegação das coleções numa forma comum é possível porque:
Iterable<T> é uma superinterface de Collection<T>.
Mecanismo provido por Iterator<T> provê:
Acesso sequencial a todos os elementos da coleção, sem repetição;
Independência da organização da coleção;
Acesso individual aos elementos.
14/10/2015 (C) 2015, Jandl. 138
14/10/2015
70
14/10/2015 (C) 2015, Jandl. 139
São dutos abstratos capazes de realizar a transmissão de dados de uma fonte para um destino. Um array, uma string, um arquivo ou um dispositivo
podem funcionar como fonte dos dados, que serão transportados pelo duto, ou como destino para armazenar os elementos recebidos.
Praticamente todo o tratamento de arquivos e dispositivos se baseia no uso de streams e de suas operações de leitura (da fonte) e escrita (no destino).
14/10/2015 (C) 2015, Jandl. 140
14/10/2015
71
O novo pacote java.util.stream permite associar um stream a uma coleção.
O conteúdo da coleção pode ser percorrido em sequência e sem a repetição de qualquer um de seus elementos.
Torna possível aplicar homogeneamente uma operação específica a todo o conteúdo de uma coleção.
Operações possíveis de transformação são a filtragem, o mapeamento ou a redução.
14/10/2015 (C) 2015, Jandl. 141
Operação de separação de elementos particulares de uma coleção que atendem um critério de seleção específico: cada elemento satisfaz um predicado pré-estabelecido.
Exemplo: Uma coleção de objetos Automovel, que descrevem
veículos por meio de sua marca, modelo, ano de fabricação, placa, cidade e cor.
Uma operação de filtragem poderia determinar o conjunto de veículos de uma determinada marca, ou de uma cidade, ou de uma combinação destes atributos.
14/10/2015 (C) 2015, Jandl. 142
14/10/2015
72
Consiste na associação de cada elemento a uma outra informação, ou até mesmo sua substituição por outro.
Exemplo:
Uma coleção de objetos Automovel.
Uma operação de mapeamento pode associar informações técnicas dos modelos com seus elementos ou substituir a placa por outro padrão de identificação.
14/10/2015 (C) 2015, Jandl. 143
Efetua a agregação da informação contida pelo elemento ou por um de seus atributos produzindo um resultado final.
Exemplo:
Uma coleção de objetos Automovel.
Uma operação de redução poderia determinar a idade média dos veículos ou a contagem daqueles com uma cor particular.
14/10/2015 (C) 2015, Jandl. 144
14/10/2015
73
Pacote java.util.stream contém interfaces e classe que suportam o estilo funcional onde o conteúdo de uma coleção é percorrido sequencialmente (como num iterator).
Elementos principais: interface BaseStream<T, S>
interface Stream<T>
interface DoubleStream
interface IntStream
interface LongStream
classe Collectors14/10/2015 (C) 2015, Jandl. 145
Novo método forEach(Consumer<T>), adicionado à interface Iterable<T> (superinterface de Collection<T>), possibilita simplificar a navegação de coleções.
Permite indicar uma função Consumer<T> com uso de uma expressão lambda:
// exibe todos os elementos da coleçãocolecao.forEach(e -> System.out.println(e));
14/10/2015 (C) 2015, Jandl. 146
14/10/2015
74
Uso do método forEach(Consumer<T>) requer um objeto que implemente a interface funcional Consumer<T>, o que é facilmente realizado por meio de uma expressão lambda: Stream<Double> stream1 = lista.stream();
stream1.forEach(e -> System.out.print(e + ", "));
Navegação numa coleção por meio de um Stream<T> é tão simples quanto com o uso de um Iterator<T>.
14/10/2015 (C) 2015, Jandl. 147
Os streams possuem algumas características distintas:
Não realizam o armazenamento ou retenção de dados, pois são dutos lógicos entre um produtor e um consumidor.
São consumíveis, ou seja, depois que um dado é obtido, não existe possibilidade de retrocesso.
Depois de usados, devem ser descartados e obtidos novamente para uma outra utilização.
14/10/2015 (C) 2015, Jandl. 148
14/10/2015
75
Exemplo
import java.util.ArrayList;import java.util.List;import java.util.stream.Stream;public class StreamDemo1 {
public static void main(String[] args) {// Cria lista com valores reaisList<Integer> lista = new ArrayList<>();for (int i = 1; i <= 15; i++) {
lista.add((int)Math.pow(i, 2));}// Exibição da lista por meio de toString (implícito)System.out.println(lista);// Obtém stream sequencial de tipo adequadoStream<Integer> stream1 = lista.stream();// Uso de forEach em stream com expressão lambdastream1.forEach(e -> System.out.print(e + ", "));System.out.println();// Alternativa compacta
lista.stream().forEach(e -> System.out.printf("%d; ", e));System.out.println();
} }
14/10/2015 (C) 2015, Jandl. 149
Uso de lambdas.
Uso de streams.
14/10/2015 (C) 2015, Jandl. 150
14/10/2015
76
Consiste na seleção de um subconjunto de elementos de uma estrutura de dados ou coleção que atende a um critério ou predicado específico. Iterator<Double> iterator = lista.iterator();
while (iterator.hasNext()) {// obtém elementodouble elemento = iterator.next();// testa elementoif (elemento > LIMITE) {
// exibe elemento > LIMITE System.out.println(elemento);
}}
14/10/2015 (C) 2015, Jandl. 151
Com a API provida por Stream<T> o trecho anterior, baseado no uso de um Iterator<T>, se reduz a: lista.stream().filter(
elemento -> elemento > LIMITE ); Aqui ao stream associado à coleção é aplicado o
método filter(Predicate<T>), o qual é uma interface funcional e possibilita o usode uma expressão lambda.
14/10/2015 (C) 2015, Jandl. 152
14/10/2015
77
Exemploimport java.util.*;import java.util.stream.*;public class StreamDemo2 {public static void main(String[] args) {// Cria lista com valores reaisList<Double> lista = new ArrayList<>();for (int i = 0; i < 180; i += 10) {lista.add(Math.sin(Math.toRadians(i)));}// Uso implícito de lista.toString()System.out.println(lista);// Define um valor limitedouble LIMITE = 0.95;// Obtém stream sequencial adequadoStream<Double> stream1 = lista.stream();// Aplica filtro com expressão lambdaStream<Double> maiores = stream1.filter(e -> e > LIMITE);// Uso de forEach com expressão lambdaSystem.out.println("Maiores que 0.95:");maiores.forEach(e -> System.out.println("\t" + e));// Obtém (novamente) stream sequencial adequadoStream<Double> stream2 = lista.stream();// Aplica filtro com expressão lambda e adiciona em outra coleçãoList<Double> menores = stream2
.filter(e -> e <= 0.2)
.collect(Collectors.toList());// Verifica tipo do objeto retornado por CollectorsSystem.out.println(menores.getClass().getName());// Uso de forEach em lista com expressão lambdaSystem.out.println("Menores que 0.2:");menores.forEach(e -> System.out.println("\t" + e));} }
14/10/2015 (C) 2015, Jandl. 153
Uso de lambdas.
Uso de lambdas em estilo funcional.
Uso de streams.
14/10/2015 (C) 2015, Jandl. 154
14/10/2015
78
Operação de transformar elementos de uma coleção em outros, segundo função de mapeamento/transformação que permite obter novo conjunto associado de valores.
Métodos existentes para isto são:
map usa Function<T>
mapToDouble usa ToDoubleFuntion<T>
mapToInt usa ToIntFunction<T>
14/10/2015 (C) 2015, Jandl. 155
Um exemplo hipotético de mapeamento:
DoubleStream resultado =lista.stream().mapToDouble(e -> e/2.0);
Aqui é produzida a soma das metades dos elementos obtidos por meio do streamutilizado.
14/10/2015 (C) 2015, Jandl. 156
14/10/2015
79
Exemploimport java.util.*;import java.util.stream.*;
public class StreamDemo3 {public static void main(String[] args) {
// Cria lista com valores inteirosList<Integer> lista = new ArrayList<>();for (int i = 0; i < 5; i++) lista.add(i);System.out.println(lista); // exibe lista// Obtém stream dos quadrados dos elementosIntStream quadrados = lista.stream()
.mapToInt((e) -> e * e);quadrados.forEach((e) -> System.out.println("\t" + e));// Cria Stream a partir de duplas de valores reaisStream<Dupla> streamDuplas = Stream.of(new Dupla(81.5, 1.69),
new Dupla(52.5, 1.62), new Dupla(64.2, 1.66));// Obtém stream dos IMCs dos elementos com massa maior que 80DoubleStream imc = streamDuplas
.filter((d) -> d.valor1 > 80)
.mapToDouble((d) -> d.getValor1()/Math.pow(d.valor2,2));imc.forEach((e) -> System.out.println("[imc] " + e));
}}
// classe utilitáriaclass Dupla {
public double valor1, valor2; // campospublic double getValor1() {return valor1; } // getterpublic Dupla(double valor1, double valor2) { // construtor
this.valor1 = valor1; this.valor2 = valor2;}
}
14/10/2015 (C) 2015, Jandl. 157
Uso de streams e lambdas.
Uso de lambdas em estilo funcional.
Uso de streams.
14/10/2015 (C) 2015, Jandl. 158
14/10/2015
80
Operação que toma sequência de elementos de entrada; aplica função de combinação em cada um; e produz um resultado final.
Os métodos existentes para isto são:
sum
max
count
14/10/2015 (C) 2015, Jandl. 159
Exemplo
import java.util.*;import java.util.stream.Collectors;public class StreamDemo4 {public static void main(String[] args) {List<Double> listaX = new ArrayList<>();for (double x = 0; x < 10; x+=0.5) { listaX.add(x); }System.out.println("X:" + listaX);Iterator<Double> iterator = listaX.iterator();double totalX = 0;while (iterator.hasNext()) {
totalX += iterator.next();}System.out.println("Total(X):" + totalX);Somador somador = new Somador();listaX.forEach(x -> somador.add(x));System.out.println("Total(X):" + somador.getTotal());totalX = listaX.stream()
.mapToDouble(e -> e) // mapeamento
.sum(); // reduçãoSystem.out.println("Total(X):" + totalX);// Mapeamento restrito de X em YList<Double> listaY = listaX.stream()
.filter(x -> x>3 && x<7) // filtragem
.map(x -> x*x -10*x +24) // mapeamento
.collect(Collectors.toList()); // coletaSystem.out.println("Yrestrito:" + listaY);// Contagem e máximo via redução predefinidaSystem.out.printf("Num(Yrestrito):%d valores\n",listaY.stream().count()); // reduçãoOptional<Double> maxY = listaY.stream()
.max(Double::compare); // redução System.out.println("Max(Yrestrito):" + maxY.get());double totalY = listaY.stream()
.reduce(0.0, (acc, e) -> acc + e); // reduçãoSystem.out.println("Total(Yrestrito):" + totalY);} }
class Somador { // classe utilitáriaprivate double total;public Somador() { preset(0); }public Somador(double v) { preset(v); }public void add(double v) { total += v; }public double getTotal() {
return total; }protected void preset( double v) {
total = v; }public void reset() { preset(0); }
}
14/10/2015 (C) 2015, Jandl. 160
Cria lista com valores reais.
(1) Totalização via navegação com iterator.
(2) Totalização via navegação com forEach.
(3) Totalização via redução.
(3) Totalização via redução.
(4) Totalização via reduçãodefinida.
14/10/2015
81
14/10/2015 (C) 2015, Jandl. 161
As operações em massa simplificam enormemente a manipulação de conteúdo de coleções, num estilo de programação funcional, que emprega os lambda com vantagens.
As funcionalidades obtidas são em alguns casos equivalentes ao uso de banco de dados (mas sem o ônus de sua utilização) e, em outras situações, são superiores, pois tratam dados que não estão contidos em bancos de dados.
14/10/2015 (C) 2015, Jandl. 162
14/10/2015
82
Java - Guia do Programador. 3ª. Edição.Peter Jandl Junior.Novatec. 2015.
The Java Tutorial – Lesson::AggregateOperations.https://docs.oracle.com/javase/tutorial/collections/streams/
Lambdas and Streams in Java SE 8: Making Bulk Operations simplehttp://pt.slideshare.net/JAXLondon2014/lambdas-and-streams-in-java-se-8-making-bulk-operations-simple-simon-ritter
14/10/2015 (C) 2015, Jandl. 163
14/10/2015 (C) 2015, Jandl. 164
Dançarinos Kuda-Lumping, Java, Indonésia.
14/10/2015
83
Uma nova e consistente API para lidar com datas, horários e intervalos de tempo.
14/10/2015 (C) 2015, Jandl. 165
Suporte para data e hora no Java anterior à versão 8 era pouco intuitivo e confuso.
Elementos principais:
Classe java.util.Date [desde 1.0]
Classe java.util.Calendar [desde 1.1]
Classe java.util.GregorianCalendar [desde 1.1]
Pouca consistência entre elementos e realidade, classes inadequadas para uso de threads.
14/10/2015 (C) 2015, Jandl. 166
14/10/2015
84
14/10/2015 (C) 2015, Jandl. 167
Java 8 inclui nova API para datas, horários e intervalos de tempo no pacote java.time.
Nova API foi baseada na biblioteca JodaTimee é centrada em três conceitos principais:
classes de valor imutável;
projeto dirigido ao domínio data-hora; e
existência de calendários diferentes.
14/10/2015 (C) 2015, Jandl. 168
14/10/2015
85
Define datas, horários e intervalos com rigor, mas de uso intuitivo.
Projetada para uso multithreaded, pois quaisquer alterações em seus objetos gera novos objetos, sem afetar threads que os compartilham.
Possibilita operar calendários segundo a ISO8601 e também outros diferentes, como japonês, chinês ou tailandês.
14/10/2015 (C) 2015, Jandl. 169
Classes principais:
Clock
Instant
LocalDate
LocalTime
LocalDateTime
ZonedDateTime
Duration
14/10/2015 (C) 2015, Jandl. 170
14/10/2015
86
14/10/2015 (C) 2015, Jandl. 171
Classe java.time.Clock permite obter um relógio capaz de prover acesso:
ao tempo no formato UTC (Universal Time Coordinated),
a data e horário locais (segundo fuso horário do sistema).
Um relógio pode ser obtido com método fábrica systemUTC():
final Clock clock = Clock.systemUTC();
14/10/2015 (C) 2015, Jandl. 172
14/10/2015
87
Classe java.time.Instant representa um instante de tempo em formato UTC com representação ISO8601.
Um relógio pode fornecer o tempo como contagem de tempo em milissegundos(à partir de 01/01/1970 00:00):
long agoraMillis = clock.millis();
Que equivale à:
long agoraMillis2 = System.currentTimeMillis();
14/10/2015 (C) 2015, Jandl. 173
Exemplo
package jandl.j8d;import java.time.Clock;import java.time.Instant;import java.util.Date;
public class TesteClock {public static void main(String[] args) {
// Obtém relógiofinal Clock clock = Clock.systemUTC();// Exibição de ClockSystem.out.println("Clock : " + clock.instant());System.out.println("Clock : " + clock.millis());// Obtém instante atual como UTC usando ClockInstant agora = clock.instant();System.out.println("Instante: " + agora);System.out.println("Instante: " + agora.toEpochMilli());// Obtém instante atual como UTC usando System e DateSystem.out.println("System : " +
System.currentTimeMillis());Date data = new Date();System.out.println("Date : " + data);System.out.println("Date : " + data.getTime());
// Pausa de 10 segundostry {
Thread.sleep(10000);} catch (InterruptedException ie) {}System.out.println();
// Reexibição de Clock, Instant, System e DateSystem.out.println("Clock : " + clock.instant());System.out.println("Clock : " + clock.millis());System.out.println("Instante: " + agora);System.out.println("Instante: " + agora.toEpochMilli());System.out.println("System : " +
System.currentTimeMillis());System.out.println("Date : " + data);System.out.println("Date : " + data.getTime());
}}
14/10/2015 (C) 2015, Jandl. 174
Obtém relógio UTC.
Data e hora obtidas convencionalmente.
Obtém instante UTC.
Reexibição dos elementos após pausa.
14/10/2015
88
ExemploClock : 2015-09-28T15:13:32.529ZClock : 1443453212622Instante: 2015-09-28T15:13:32.622ZInstante: 1443453212622System : 1443453212622Date : Mon Sep 28 12:13:32 BRT 2015Date : 1443453212623
Clock : 2015-09-28T15:13:42.648ZClock : 1443453222648Instante: 2015-09-28T15:13:32.622ZInstante: 1443453212622System : 1443453222648Date : Mon Sep 28 12:13:32 BRT 2015Date : 1443453212623
14/10/2015 (C) 2015, Jandl. 175
Clock acompanha o tempo.
Instant não acompanha o tempo.
14/10/2015 (C) 2015, Jandl. 176
14/10/2015
89
Classe java.time.LocalDate retém apenas a informação relativa a uma data, sem conteúdo de horário, conforme o calendário definido pela ISO8601:
// Usando relógio local
LocalDate dataLocal = LocalDate.now();
// Usando relógio fornecido
LocalDate dataLocalClock =LocalDate.now(clock);
14/10/2015 (C) 2015, Jandl. 177
Classe java.time.LocalTime retém apenas a informação relativa a um horário, sem conteúdo de data:
// Usando relógio local
LocalTime horarioLocal = LocalTime.now();
// Usando relógio fornecido
LocalTime horarioLocalClock =LocalTime.now(clock);
14/10/2015 (C) 2015, Jandl. 178
14/10/2015
90
Exemplo
package jandl.j8d;
import java.time.Clock;import java.time.LocalDate;import java.time.LocalTime;
public class TesteLocalDateLocalTime{
public static void main(String[] a) {// Obtém relógiofinal Clock clock = Clock.systemUTC();
// Obtém data atual localfinal LocalDate dataLocal = LocalDate.now();final LocalDate dataLocalClock = LocalDate.now(clock);System.out.println("Data : " + dataLocal);System.out.println("Data : " + dataLocalClock);
// Obtém horário atual localfinal LocalTime horarioLocal = LocalTime.now();final LocalTime horarioLocalClock = LocalTime.now(clock);System.out.println("Horário: " + horarioLocal);System.out.println("Horário: " + horarioLocalClock);
// Pausa de 2 minutostry {
Thread.sleep(120000);} catch (InterruptedException ie) {}
// Reexibição de data e horário localSystem.out.println();System.out.println("Data : " + dataLocal);System.out.println("Data : " + dataLocalClock);System.out.println("Horário: " + horarioLocal);System.out.println("Horário: " + horarioLocalClock);
}}
14/10/2015 (C) 2015, Jandl. 179
Obtém relógio UTC.
Obtém data local.
Reexibição dos elementos após pausa.
Obtém horário local.
Classe java.time.LocalDateTime contém as informações conjugadas de data e horário:
// Usando relógio local
LocalDateTime dataHoraLocal = LocalDateTime.now();
// Usando relógio fornecido
LocalDateTime dataHoraLocalClock =LocalDateTime.now(clock);
14/10/2015 (C) 2015, Jandl. 180
14/10/2015
91
Exemplopackage jandl.j8d;import java.time.Clock;import java.time.LocalDateTime;
public class TesteLocalDateTime {public static void main(String[] a) {
// Obtém relógiofinal Clock clock = Clock.systemUTC();
// Obtém data e horário atual localfinal LocalDateTime dataHoraLocal =
LocalDateTime.now();final LocalDateTime dataHoraLocalClock =
LocalDateTime.now(clock);System.out.println("DataHora: " +
dataHoraLocal);System.out.println("DataHora: " +
dataHoraLocalClock);}
}
14/10/2015 (C) 2015, Jandl. 181
Obtém relógio UTC.
Obtém data e hora local.
Exibição dos elementos.
Data específica pode ser obtida com:
LocalDate data = LocalDate.of(2015, 10, 15);
Horário específico pode ser obtido com:
LocalTime horario = LocalTime.of(13, 00, 00);
Data e horário específicos podem ser obtido com:
LocalDateTime datahorario =LocalDateTime.of(2015, 10, 15, 13, 00, 00);
14/10/2015 (C) 2015, Jandl. 182
14/10/2015
92
Exemplopackage jandl.j8d;import java.time.LocalDate;import java.time.LocalDateTime;import java.time.LocalTime;
public class TesteFabricasDateTime {public static void main(String[] args) {
// Data criada com método fábricafinal LocalDate republica = LocalDate.of(2015, 11, 15);System.out.println(republica);
// Horário criado com método fábricafinal LocalTime oitoDaNoite = LocalTime.of(20, 00, 00);System.out.println(oitoDaNoite);
// Combinação de data+horafinal LocalDateTime ldt1 = republica.atTime(oitoDaNoite);final LocalDateTime ldt2 = oitoDaNoite.atDate(republica);System.out.println(ldt1 + " = " + ldt2);
// Data Horário criado com método fábricafinal LocalDateTime natal =
LocalDateTime.of(2015, 12, 25, 00, 00, 00);System.out.println(natal);
}}
14/10/2015 (C) 2015, Jandl. 183
Cria data específica.
Combina data e hora.
Exibição dos elementos.
Cria horário específica.
Classe java.time.ZonedDateTime contém as informações conjugadas de data e horário para um local específico (fuso horário): // Usando fuso horário local
ZonedDateTime zonedDatetime =ZonedDateTime.now();
// Usando relógio fornecido
ZonedDateTime zonedDatetimeFromClock =ZonedDateTime.now(clock);
// Usando fuso horário indicado
ZonedDateTime zonedDatetimeFromZone1 =ZonedDateTime.now(ZoneId.of("America/New_York"));
14/10/2015 (C) 2015, Jandl. 184
14/10/2015
93
Exemplopackage jandl.j8d;import java.time.Clock;import java.time.ZoneId;import java.time.ZonedDateTime;
public class TesteZonedDateTime {
public static void main(String[] args) {// Obtém relógiofinal Clock clock = Clock.systemUTC();
// Obtém data e horário conforme fusos específicosfinal ZonedDateTime zonedDatetime = ZonedDateTime.now();final ZonedDateTime zonedDatetimeFromClock =
ZonedDateTime.now(clock);final ZonedDateTime zonedDatetimeFromZone1 =
ZonedDateTime.now(ZoneId.of("America/New_York"));
final ZonedDateTime zonedDatetimeFromZone2 =ZonedDateTime.now(
ZoneId.of("Europe/Lisbon"));
// Exibe data e horário conforme fusos específicosSystem.out.println(zonedDatetime);System.out.println(zonedDatetimeFromClock);System.out.println(zonedDatetimeFromZone1);System.out.println(zonedDatetimeFromZone2);
}}
14/10/2015 (C) 2015, Jandl. 185
Obtém relógio local.
Exibição dos elementos.
Cria data/horário do local e com relógio dado.
Cria data/horário para fuso específico.
14/10/2015 (C) 2015, Jandl. 186
14/10/2015
94
Classe java.time.Duration representa intervalos de tempo com o armazenamento interno da contagem de segundos e nanosegundos.
Pode ser obtida pela diferença entre duas datas, horários ou data-horário combinados: // Define duas datas início e fim
Temporal inicio = LocalDate.of(2002, Month.FEBRUARY, 20);
Temporal fim = LocalDate.of(2015, Month.JULY, 31);
Duration duracaoIF = Duration.between(inicio, fim);
14/10/2015 (C) 2015, Jandl. 187
Intervalos maiores que a idade estimada do universo podem ser representados .
java.time.Temporal provê uma interface comum para as classes LocalDate, LocalTime e LocalDateTime que permite sua manipulação, i.e., podem ser avançadas ou retrocedidas temporalmente: minus, minusYears, minusMonths, minusWeeks,
minusDays, minusHours, minusMinutes, minusSeconds, minusNanos
plus, minusYears, plusMonths, plusWeeks, plusDays, plusHours, plusMinutes, plusSeconds, plusNanos
asas
14/10/2015 (C) 2015, Jandl. 188
14/10/2015
95
Exemplo
package jandl.j8d;import java.time.*;
public class TesteDuration {public static void main(String[] args) {
// Define duas datas-horário, início e fimfinal LocalDateTime inicio = LocalDateTime.of(2002, Month.FEBRUARY, 20, 0, 0, 0);final LocalDateTime fim = LocalDateTime.of(2015, Month.JULY, 31, 23, 59, 59);
// Determina intervalo entre datas fim-inicio (duração positiva)final Duration duracaoIF = Duration.between(inicio, fim);// Exibe intervalo e seus detalhesSystem.out.printf("Duracao [%s - %s] = %s\n”, fim, inicio, duracaoIF);System.out.printf("Dias=%0,3d Horas=%0,3d Min=%0,3d Seg=%0,3d\n\n",
duracaoIF.toDays(), duracaoIF.toHours(),duracaoIF.toMinutes(), duracaoIF.toMillis()/1000);
// Define nova data por meio manipulação de data existentefinal LocalDateTime fimMenos10 = fim.minusDays(10);
// Determina intervalo entre datas inicio-fim (duração negativa)final Duration duracaoFI = Duration.between(fimMenos10, inicio);// Exibe intervalo e seus detalhesSystem.out.printf("Duracao [%s - %s] = %s\n", inicio, fimMenos10, duracaoFI);System.out.printf("Dias=%0,3d Horas=%0,3d Min=%0,3d Seg=%0,3d\n\n",
duracaoFI.toDays(), duracaoFI.toHours(),duracaoFI.toMinutes(), duracaoFI.toMillis()/1000);
// Define um intervalo por meio de método-fábricaDuration dezDias = Duration.ofDays(10);// Novo intervalo obtido pela manipulação de intervalo existenteDuration duracaoMais11 = duracaoIF.plus(dezDias).plusDays(1);// Exibe novo intervaloSystem.out.printf("Duracao + 11dias = %s\n", duracaoMais11);
}}14/10/2015 (C) 2015, Jandl. 189
Datas inicio e fim.
Define e exibe intervalo.
Calcula e exibe intervalo positivo.
Calcula e exibe intervalo negativo.
Manipulação de data.
14/10/2015 (C) 2015, Jandl. 190
14/10/2015
96
Antigas classes foram mantidas para manter a compatibilidade com aplicações desenvolvidas antes do Java 8.
Pequena alteração foi feita na classe java.util.Date para integrar aplicações que usam a antiga API com a nova:
Instant Date.toInstant()
14/10/2015 (C) 2015, Jandl. 191
14/10/2015 (C) 2015, Jandl. 192
14/10/2015
97
Nova API DateTime é um avanço substancial em relação as antigas classes da API.
Oferecem utilização simples, consistente em termos de sua semântica e também rigorosas em relação ao domínio do tempo.
São imutáveis e simplificam o desenvolvimento de aplicações multithreaded.
Recomenda-se que o desenvolvimento de novas aplicações dê preferência ao uso da nova API.
14/10/2015 (C) 2015, Jandl. 193
Java - Guia do Programador. 3ª. Edição.Peter Jandl Junior.Novatec. 2015.
Trail: Date Time (The Java Tutorials).https://docs.oracle.com/javase/tutorial/datetime/
Package java.time (Java Platform Standard Edition 8 Documentation).https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html
Java 8 Date/Time API Tutorial.http://examples.javacodegeeks.com/core-java/java-8-datetime-api-tutorial/
14/10/2015 (C) 2015, Jandl. 194
14/10/2015
98
14/10/2015 (C) 2015, Jandl. 195
Mar de Java, Java, Indonésia.
14/10/2015 (C) 2015, Jandl. 196
14/10/2015
99
Adições da versão 8 são, de fato, importantes: Métodos de extensão para interfaces
Expressões Lambda
Referências para métodos
Streams e operações em massa para coleções
Nova API DateTime
Paralelização de operações
Anotações melhoradas São substanciais, podem e devem ser
aproveitadas na construção de novas aplicações!
14/10/2015 (C) 2015, Jandl. 197
Conteúdo deste minicurso!
14/10/2015 (C) 2015, Jandl. 198