Java 8 - New Features
-
Upload
rafael-brito-de-oliveira -
Category
Software
-
view
167 -
download
2
Transcript of Java 8 - New Features
55 novas featuresDocumentação Oracle
Mas falaremos somente sobre 5 delas…
LinguagemLambda ExpressionsMethod Reference
Default Method
APIStream
Date-Time
SegurançaJavaFX
InternacionalizaçãoDeploymentScriptingPack200
IO e NIOjava.lang e java.util
Packages
Java Mission ControlJDBC
Java DBNetworking
ConcorrênciaHotSpot
Tools
Outras Melhorias...
(int x, int y) -> {x + y;}
(a, b) -> {System.out.println(a);System.out.println(b);}
() -> 42
(String s) -> System.out.println(s)
Por que Lambda no Java?● 1 linha de código ao invés de 5;
● programação funcional;
● referência de métodos;
● Streams -> Filter/Map/Reduce;
● execução mais rápida que Classe Anônima;
Quase função de 1º ordem…● pode ser passada como parâmetro;● pode ser retornada em um método;● pode ser armazenada em uma variável;
Por que quase?Não existe um tipo função de verdade na JVM;O java converte lambda em interfaces funcionais;
Antes…
new Thread(new Runnable() {@Overridepublic void run() {
System.out.println("Classe Anônima");}
}).start();
Interfaces Funcionais
@FunctionalInterfacepublic interface Runnable() {
public abstract void run();}
REGRA: apenas um método.
Unexpected @FunctionalInterface annotationTestable is not a functional interface
@FunctionalInterfacepublic interface Testable() {
public boolean test();public boolean doOtherThing();
}
Inferências@FunctionalInterfacepublic interface Testable {
public boolean test(int a, int b);}
"hum, deve retornar um boolean".
"hum, recebe 2 parâmetros do tipo
int"
new Test().execute(2, 4, (a, b) -> a > b))
class Test {public boolean execute(int a, int b,
Testable testable) {return testable.test(a, b);
}}
Criando uma Instância Lambda
Runnable runnable = () -> System.out.println("Lambda");
Callable callable = () -> System.out.println("Lambda");
Novo Pacote: java.util.functionPredicate<T> - método com um parâmetro do tipo T e retorno do tipo boolean.T -> boolean
Consumer<T> - método com um parâmetro do tipo T e sem retorno.T -> {}
Function<T, R> - método com um parâmetro do tipo T e retorno do tipo R.T -> R
Supplier<T> - método sem parâmetros e retorno do tipo T.() -> T
BiFunction<T, R, U> - método com dois parâmetros. um do tipo T outro do tipo R e retorno do tipo U.(T, R) -> U
Referência de MétodosLambda Método
x -> String.valueOf(x) String::valueOf
x -> x.toString() Object::toString
() -> new ArrayList<>() ArrayList::new
List<String> cars = Arrays.asList(“Corsa”, “Opala”, “Fusca”, “Focus”);
Collections.sort(cars, (a, b) -> a.compareTo(b));Collections.sort(cars, String::compareTo);
System.out.println(cars);
Resultado:
[Corsa, Focus, Fusca, Opala]
4 Tipos de Method Reference
Tipo Sintaxe Exemplo
Referência a um método estático Class:staticMethodName String::valueOf
Referência a um método de uma instância
object:instanceMethodName x::toString
Referência a um método de uma instância arbritária qualquer, desde que seja do tipo Class
Class::instanceMethodName String::toString
Referencia a um construtor ClassName::new String::new
Default MethodsMethod DefenderVirtual Methods
Provê um mecanismo para estender uma interface existente sem quebrar a retrocompatibilidade
java.util.Listdefault void replaceAll(UnaryOperator<E> operator)default void sort(Comparator<? super E> c)default Spliterator<E> spliterator()
@Overridedefault Spliterator<E> spliterator() {
return Spliterators.spliterator(this, Spliterator.ORDERED);
}
Um método conveniente de iterar sobre uma coleção de maneira fluente.
StreamJEP 107 -> Bulk and Data Structure for Collections
Anatomia da API Stream
filter(x -> x > 3)
sorted((a, b) -> a.compareTo(b))
map(x -> x * 2)
forEach(x -> System.out.println(x))
PIPELINE
Fonte -> {Collections, Iterator,Resources,Generators}
Operação de Finalização -> produzem resultados finais
Operações Intermediárias
Criando StreamVersão varargsStream.of(varargs...)
Versão InfinitaStream.generate(Supplier<T>) -> tem o método T get()
Versão InfinitaStream.iterate(seed, UnaryOperator<T> f) -> tem o método <T> UnaryOperator<T>identity()
Versão Strem a partir de um ListStream<Integer> number = Arrays.asList(1, 2, 3).stream()
Versão paralelaStream<Integer> number = Arrays.asList(1, 2, 3).parallelStream()
Tipos de OperaçõesIntermediárias
● Sempre retornam um novo Stream;● Executam quantas operações encadeadas forem necessárias;● Não inicia o pipeline de execução;
...métodos● distinct() ● sorted() ● sorted(Comparator) ● limit(long) ● map(Function) ● filter(Predicate)
Tipos de OperaçõesFinalização
● Pode retornar um objeto, uma collection, ou void;● Inicia o pipeline de execução;● Depois de executar esta fase, o Stream, não pode ser reutilizado;
...métodos● reduce(BinaryOperator)● forEach(Consume)● findFirst()● noneMatch(Predicate)● collect()
Collection vs Stream
Sequência de elementos Sequência de elementos
Estrutura de dados em memória Elementos percorridos uma única vez
Iteração externa Iteração interna
Tamanho finito Tamanho também pode ser infinito
Pode alterar a própria Coleção Retorna sempre um novo Stream
Iterando sobre uma Collection
● Verboso;● Paralelismo manual;
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);List<Integer> evenNumbers = new ArrayList<>();for (Integer number : numbers) {
if (number % 2 == 0) {evenNumbers.add(i);
}}
Iterando sobre um StreamList<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);//versão normalList<Integer> evenNumbers = numbers.stream().filter(n -> n % 2 == 0).collect(toList());//versão paralelaList<Integer> evenNumbers = numbers.parallelStream().filter(n -> n % 2 == 0).collect(toList());
● API Fluente: processo de execução encadeado;● Execução Lazy: elementos computados somente quando necessários;● Paralelismo Nativo com a utilização do método .parallelStream();
Guavaprivate void removeDuplicate(Iterable<Sale> sales) { final Iterable<Long> inscriptionIds = transform(sales, new Function<Sale, Long>() { @Override public Long apply(Sale input) { return input.getInscriptionId(); } }); final List<Sale> existentSales = new ArrayList<Sale>(); existentSales.addAll(saleRepository.findByInscriptionIdInAndType(inscriptionIds, ORIGINAL)); removeIf(sales, new Predicate<Sale>() { @Override public boolean apply(final Sale sale) { return any(existentSales, new Predicate<Sale>() { @Override public boolean apply(final Sale input) { return sale.getInscriptionId().equals(input.getInscriptionId()); } }); } }); }}
Stream
List<Sale> sales = Arrays.asList(new Sale(123l), new Sale(456l));
Stream<Sale> salesStream = sales.stream();Stream<Sale> salesStream2 = sales.stream();
List<Sale> salesExistents = SaleRepository.findByInscriptionId(salesStream.map(n -> n.getInscriptionId()).collect(Collectors.toList()));
List<Long> inscriptionsExistents = salesExistents.stream().map(n -> n.getInscriptionId()).collect(Collectors.toList());
salesStream2.filter(n -> !inscriptionsExistents.contains(n)).forEach(System.out::println);
Nova API de Datas
● Package java.time● Baseada na biblioteca Joda-Time● Substitui as problemáticas java.util.Date e java.util.
Calendar● Divisão de conceitos:
○ Datas para humanos (dia, hora, mês, dia da semana…)○ Datas para computadores (milisegundos, nanosegundos, instantes…)
Nova API de Datas● Date
LocalDate hoje = LocalDate.now();System.out.println(hoje); // 2014-11-07 (formato ISO-8601 yyyy-MM-dd)
LocalDate natal = LocalDate.of(2014, Month.DECEMBER, 25);System.out.println(natal); // 2014-12-25
System.out.println(natal.getDayOfWeek().toString()); // THURSDAY (imprime por extenso)System.out.println(natal.plusDays(7)); // 2015-01-01
● TimeLocalTime time = LocalTime.now();System.out.println(time); // 12:01:45.382System.out.println(time.getHour()); // 12System.out.println(time.getSecond()); // 45System.out.println(time.plusHours(1)); // 13:01:45.382
Nova API de Datas● DateTime
LocalDateTime dateTime = LocalDateTime.now();System.out.println(dateTime); // 2014-11-07T12:01:45.382
● TimezoneZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("Europe/Paris"));System.out.println(zonedDateTime); // 2014-11-06T21:28:02.102+01:00[Europe/Paris]
OffsetDateTime offsetDateTime = OffsetDateTime.now(ZoneId.of("+07:00"));System.out.println(offsetDateTime); // 2014-11-07T03:28:02.102+07:00]
Nova API de Datas● Instant
Instant instant = Instant.now();System.out.println(instant); // 2014-11-06T20:40:48.133ZSystem.out.println(instant.plusMillis(100)); // 2014-11-06T20:40:48.233ZSystem.out.println(instant.plusNanos(1)); // 2014-11-06T20:40:48.133000001Z
● DurationLocalTime inicioApresentacao = LocalTime.of(11, 00);LocalTime fimApresentacao = LocalTime.of(12, 30);Duration duration = Duration.between(inicioApresentacao, fimApresentacao);System.out.println(duration); // PT1H30MSystem.out.println(duration.toMillis()); // 5400000System.out.println(duration.toNanos()); // 5400000000000
Nova API de Datas● Period
LocalDate hoje = LocalDate.now();LocalDate natal = LocalDate.of(2014, Month.DECEMBER, 25);Period period = Period.between(hoje, natal);System.out.println(period); // P1M18D
● Formatando (adeus SimpleDateFormat)LocalDateTime dateTime = LocalDateTime.now();System.out.println(dateTime); // 2014-11-06T18:58:20.785System.out.println(dateTime.format(DateTimeFormatter.ofPattern("dd/MM/yy HH:mm")));
// 06/11/14 18:58● Integração com legado
Date date = Date.from(Instant.now());Instant instant = calendar.toInstant();...
Referênciashttp://www.slideshare.net/dgomezg/streams-en-java-8
http://www.slideshare.net/martintoshev/new-features-injdk8
http://www.slideshare.net/BjrnKimminich/java-8-streams
http://www.slideshare.net/ags313/java8-new-things
http://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html
Revista: Java Magazine, Edição 120 - Java 8 - Do Lambda ao Metaspace