novidades do java 8

99
14/10/2015 1 Prof. Ms. Peter Jandl Junior 14/10/2015 (C) 2015, Jandl. 2 Bandung, Java, Indonésia.

Upload: peter-jandl-junior

Post on 08-Feb-2017

1.018 views

Category:

Technology


0 download

TRANSCRIPT

14/10/2015

1

Prof. Ms. Peter Jandl Junior

14/10/2015 (C) 2015, Jandl. 2

Bandung, Java, Indonésia.

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

39

14/10/2015 (C) 2015, Jandl. 77

14/10/2015 (C) 2015, Jandl. 78

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