cadec 2015 - java 8beta.callistaenterprise.se/assets/presentationer/cadec-2015-java8.pdf · •...

27
| CALLISTAENTERPRISE.SE CADEC 2015 - JAVA 8 MAGNUS LARSSON 2015.01.28 1

Upload: others

Post on 29-Sep-2020

4 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: CADEC 2015 - JAVA 8beta.callistaenterprise.se/assets/presentationer/cadec-2015-java8.pdf · • Using an anonymous inner class for a callback: JAVA 8 LAMBDA EXPRESSIONS 7 asyncHttpClient.execute(url,!

| CALLISTAENTERPRISE.SE

CADEC 2015 - JAVA 8

MAGNUS LARSSON

2015.01.28

1

Page 2: CADEC 2015 - JAVA 8beta.callistaenterprise.se/assets/presentationer/cadec-2015-java8.pdf · • Using an anonymous inner class for a callback: JAVA 8 LAMBDA EXPRESSIONS 7 asyncHttpClient.execute(url,!

•  Overview

•  Lambda Expressions

•  Stream API

JAVA 8 NEW FEATURES

2

Page 3: CADEC 2015 - JAVA 8beta.callistaenterprise.se/assets/presentationer/cadec-2015-java8.pdf · • Using an anonymous inner class for a callback: JAVA 8 LAMBDA EXPRESSIONS 7 asyncHttpClient.execute(url,!

•  New Date/Time API -  Based on Joda-Time

•  Interface improvements -  Static methods and default methods

•  Optional type -  Say goodbye to NullPointerException

•  Concurrency API additions -  E.g. CompletableFuture and parallel stream operation

•  New JavaScript Engine -  Nashorn

•  PermGen space is gone -  Yeah!

•  Lambda Expressions •  Stream API

JAVA 8 NEW FEATURES - OVERVIEW

3

Page 4: CADEC 2015 - JAVA 8beta.callistaenterprise.se/assets/presentationer/cadec-2015-java8.pdf · • Using an anonymous inner class for a callback: JAVA 8 LAMBDA EXPRESSIONS 7 asyncHttpClient.execute(url,!

•  New Date/Time API -  Based on Joda-Time

•  Interface improvements -  Static methods and default methods

•  Optional type -  Say goodbye to NullPointerException

•  Concurrency API additions -  E.g. CompletableFuture and parallel stream operation

•  New JavaScript Engine -  Nashorn

•  PermGen is gone! -  Yeah!

•  Lambda Expressions •  Stream API

JAVA 8 NEW FEATURES - OVERVIEW

4

Enables Functional-style Programming

Page 5: CADEC 2015 - JAVA 8beta.callistaenterprise.se/assets/presentationer/cadec-2015-java8.pdf · • Using an anonymous inner class for a callback: JAVA 8 LAMBDA EXPRESSIONS 7 asyncHttpClient.execute(url,!

•  Overview

•  Lambda Expressions

•  Stream API

JAVA 8 NEW FEATURES

5

Page 6: CADEC 2015 - JAVA 8beta.callistaenterprise.se/assets/presentationer/cadec-2015-java8.pdf · • Using an anonymous inner class for a callback: JAVA 8 LAMBDA EXPRESSIONS 7 asyncHttpClient.execute(url,!

•  Using an anonymous inner class for a callback:

JAVA 8 LAMBDA EXPRESSIONS

6

asyncHttpClient.execute(url, !! new AsyncCompletionHandler<Response>() { ! @Override! public Response onCompleted! (Response response) { ! ! // TODO: Handle the response... ! } ! } !); !

Page 7: CADEC 2015 - JAVA 8beta.callistaenterprise.se/assets/presentationer/cadec-2015-java8.pdf · • Using an anonymous inner class for a callback: JAVA 8 LAMBDA EXPRESSIONS 7 asyncHttpClient.execute(url,!

•  Using an anonymous inner class for a callback:

JAVA 8 LAMBDA EXPRESSIONS

7

asyncHttpClient.execute(url, !! new AsyncCompletionHandler<Response>() { ! @Override! public Response onCompleted! (Response response) { ! ! // TODO: Handle the response... ! } ! } !); !

This is just overhead!!

Page 8: CADEC 2015 - JAVA 8beta.callistaenterprise.se/assets/presentationer/cadec-2015-java8.pdf · • Using an anonymous inner class for a callback: JAVA 8 LAMBDA EXPRESSIONS 7 asyncHttpClient.execute(url,!

•  Anonymous inner class

•  Lambda expression

JAVA 8 LAMBDA EXPRESSIONS

8

asyncHttpClient.execute(url, !! new AsyncCompletionHandler<Response>() { ! @Override! public Response onCompleted! (Response response) { ! ! // TODO: Handle the response... ! } ! } !); !

asyncHttpClient.execute(url, !! (Response response) -> { !! // TODO: Handle the response... ! } !); !

Gone using Lambdas!!!

Page 9: CADEC 2015 - JAVA 8beta.callistaenterprise.se/assets/presentationer/cadec-2015-java8.pdf · • Using an anonymous inner class for a callback: JAVA 8 LAMBDA EXPRESSIONS 7 asyncHttpClient.execute(url,!

•  Type inference

•  Local variables

JAVA 8 LAMBDA EXPRESSIONS

9

asyncHttpClient.execute(url, !! response -> { !! // TODO: Handle the response... ! } !); !

final DeferredResult<String> dr = ! new DeferredResult<>();!!asyncHttpClient.execute(url, !! response -> { !! // TODO: Handle the response... ! dr.setResult(response.getResponseBody()); ! } !); !

Page 10: CADEC 2015 - JAVA 8beta.callistaenterprise.se/assets/presentationer/cadec-2015-java8.pdf · • Using an anonymous inner class for a callback: JAVA 8 LAMBDA EXPRESSIONS 7 asyncHttpClient.execute(url,!

•  Functional Interfaces

-  A functional interface is an interface that defines exactly one abstract method.

-  Functional interfaces can be instantiated using lambda expressions...

SOME OF THE MAGIC BEHIND LAMBDA EXPRESSIONS

10

@FunctionalInterface public interface Predicate<T> { boolean test(T t); }

Page 11: CADEC 2015 - JAVA 8beta.callistaenterprise.se/assets/presentationer/cadec-2015-java8.pdf · • Using an anonymous inner class for a callback: JAVA 8 LAMBDA EXPRESSIONS 7 asyncHttpClient.execute(url,!

•  Overview

•  Lambda Expressions

•  Stream API

JAVA 8 NEW FEATURES

11

Page 12: CADEC 2015 - JAVA 8beta.callistaenterprise.se/assets/presentationer/cadec-2015-java8.pdf · • Using an anonymous inner class for a callback: JAVA 8 LAMBDA EXPRESSIONS 7 asyncHttpClient.execute(url,!

•  Consider the following model

INTRODUCTION TO FUNCTIONAL PROGRAMMING

12

•  How to implement:

1.  What products from category X have been ordered in the date interval M to N?

I want them sorted by their weight! 2.  What products with weight from X to Y

has been sold in orders with an order value M to N?

I want them sorted by their product id!

Page 13: CADEC 2015 - JAVA 8beta.callistaenterprise.se/assets/presentationer/cadec-2015-java8.pdf · • Using an anonymous inner class for a callback: JAVA 8 LAMBDA EXPRESSIONS 7 asyncHttpClient.execute(url,!

•  Consider the following model

INTRODUCTION TO FUNCTIONAL PROGRAMMING

13

•  Assume the following API: public interface QueryApi { !! public List<Product> getProductsByDateAndCategoryOrderByWeight( ! LocalDate minDate, ! LocalDate maxDate, ! String category); !! public List<Product> getProductsByOrderValueAndWeightOrderByProductId( ! int minOrderValue, ! int maxOrderValue, ! int minProductWeight, ! int maxProductWeight); !} !!

Page 14: CADEC 2015 - JAVA 8beta.callistaenterprise.se/assets/presentationer/cadec-2015-java8.pdf · • Using an anonymous inner class for a callback: JAVA 8 LAMBDA EXPRESSIONS 7 asyncHttpClient.execute(url,!

START WITH A IMPERATIVE SOLUTION, #1

14

public List<Product> getProductsByDateAndCategoryOrderByWeight! (LocalDate minDate, LocalDate maxDate, String category) { !! List<Order> orders = getOrders(); !! List<Product> products = new ArrayList<>(); ! for (Order order : orders) { !! // Filter on order date ! LocalDate date = order.getOrderDate(); ! if (date.isAfter(minDate) && date.isBefore(maxDate)) { !! List<OrderLine> orderLines = order.getOrderLines(); ! for (OrderLine orderLine : orderLines) { !! // Filter on product category! Product product = orderLine.getProduct(); ! if (product.getCategory().equals(category)) { ! products.add(product); ! } ! ... !

Page 15: CADEC 2015 - JAVA 8beta.callistaenterprise.se/assets/presentationer/cadec-2015-java8.pdf · • Using an anonymous inner class for a callback: JAVA 8 LAMBDA EXPRESSIONS 7 asyncHttpClient.execute(url,!

START WITH A IMPERATIVE SOLUTION, #1

15

... ! } ! } ! } !! // Remove any duplicates from the list of selected products ! products = new ArrayList<>(new HashSet<>(products)); !! // Sort on product weight! Collections.sort(products, new Comparator<Product>() { ! @Override! public int compare(Product p1, Product p2) { ! return (p1.getWeight() < p2.getWeight()) ? -1 : 1; ! } ! }); !! return products; !} !

Page 16: CADEC 2015 - JAVA 8beta.callistaenterprise.se/assets/presentationer/cadec-2015-java8.pdf · • Using an anonymous inner class for a callback: JAVA 8 LAMBDA EXPRESSIONS 7 asyncHttpClient.execute(url,!

START WITH A IMPERATIVE SOLUTION, #2

16

public List<Product> getProductsByOrderValueAndWeightOrderByProductId( ! int minOrderValue, int maxOrderValue, int minProductWeight, int maxProductWeight) { !! List<Order> orders = getOrders(); !! List<Product> products = new ArrayList<>(); ! for (Order order : orders) { !! // Filter on order value! int orderValue = order.getOrderValue(); ! if (minOrderValue <= orderValue && orderValue <= maxOrderValue) { !! List<OrderLine> orderLines = order.getOrderLines(); ! for (OrderLine orderLine : orderLines) { !! // Filter on product weight! Product product = orderLine.getProduct(); ! int productWeight = product.getWeight(); ! if (minProductWeight <= productWeight && productWeight <= maxProductWeight) { ! products.add(product); ! } ! ... !

•  A lot of code •  Most parts are the same •  Not much differs!!!

Page 17: CADEC 2015 - JAVA 8beta.callistaenterprise.se/assets/presentationer/cadec-2015-java8.pdf · • Using an anonymous inner class for a callback: JAVA 8 LAMBDA EXPRESSIONS 7 asyncHttpClient.execute(url,!

START WITH A IMPERATIVE SOLUTION, #2

17

... ! } ! } ! } !! // Remove any duplicates from the list of selected products ! products = new ArrayList<>(new HashSet<>(products)); !! // Sort on product Id ! Collections.sort(products, new Comparator<Product>() { ! @Override! public int compare(Product p1, Product p2) { ! return (p1.getId() < p2.getId()) ? -1 : 1; ! } ! }); !! return products; !} !!

Page 18: CADEC 2015 - JAVA 8beta.callistaenterprise.se/assets/presentationer/cadec-2015-java8.pdf · • Using an anonymous inner class for a callback: JAVA 8 LAMBDA EXPRESSIONS 7 asyncHttpClient.execute(url,!

•  Can we simplify this using functional programming?

•  Let’s try with plain Java 8 - Express Functions using Lambda Expressions - Declare the data processing using Java 8 Stream API

•  Lambda’s we know about already, but what about Java 8 Stream API???

INTRODUCTION TO FUNCTIONAL PROGRAMMING

18

Page 19: CADEC 2015 - JAVA 8beta.callistaenterprise.se/assets/presentationer/cadec-2015-java8.pdf · • Using an anonymous inner class for a callback: JAVA 8 LAMBDA EXPRESSIONS 7 asyncHttpClient.execute(url,!

STREAM FILTER

19

Page 20: CADEC 2015 - JAVA 8beta.callistaenterprise.se/assets/presentationer/cadec-2015-java8.pdf · • Using an anonymous inner class for a callback: JAVA 8 LAMBDA EXPRESSIONS 7 asyncHttpClient.execute(url,!

STREAM MAP

20

Page 21: CADEC 2015 - JAVA 8beta.callistaenterprise.se/assets/presentationer/cadec-2015-java8.pdf · • Using an anonymous inner class for a callback: JAVA 8 LAMBDA EXPRESSIONS 7 asyncHttpClient.execute(url,!

STREAM FLATMAP

21

Page 22: CADEC 2015 - JAVA 8beta.callistaenterprise.se/assets/presentationer/cadec-2015-java8.pdf · • Using an anonymous inner class for a callback: JAVA 8 LAMBDA EXPRESSIONS 7 asyncHttpClient.execute(url,!

•  Example #1 using Java 8 Streams

ENTERING THE FUNCTIONAL PROGRAMMING WORLD…

22

public List<Product> getProductsByDateAndCategoryOrderByWeight( ! LocalDate minDate, LocalDate maxDate, String category) { !! return getOrders() ! .stream () ! .filter (o -> o.getOrderDate().isAfter(minDate) && o.getOrderDate().isBefore(maxDate)) ! .flatMap (o -> o.getOrderLines().stream()) ! .map (ol -> ol.getProduct()) ! .filter (p -> p.getCategory().equals(category)) ! .distinct() ! .sorted ((p1, p2) -> (p1.getWeight() < p2.getWeight()) ? -1 : 1) ! .collect (Collectors.toList()); !} !

Page 23: CADEC 2015 - JAVA 8beta.callistaenterprise.se/assets/presentationer/cadec-2015-java8.pdf · • Using an anonymous inner class for a callback: JAVA 8 LAMBDA EXPRESSIONS 7 asyncHttpClient.execute(url,!

•  …and example #2…

ENTERING THE FUNCTIONAL PROGRAMMING WORLD…

23

public List<Product> getProductsByOrderValueAndWeightOrderByProductId( ! int minOrderValue, int maxOrderValue, int minProductWeight, int maxProductWeight) { !! return getOrders().stream() ! .filter (o -> minOrderValue <= o.getOrderValue() && o.getOrderValue() <= maxOrderValue) ! .flatMap (o -> o.getOrderLines().stream()) ! .map (ol -> ol.getProduct()) ! .filter (p -> minProductWeight <= p.getWeight() && p.getWeight() <= maxProductWeight) ! .distinct() ! .sorted ((p1, p2) -> ((p1.getId() < p2.getId()) ? -1 : 1)) ! .collect (Collectors.toList()); !} !!!!

•  Much better! •  But still repetitions •  Violates the DRY principle

Page 24: CADEC 2015 - JAVA 8beta.callistaenterprise.se/assets/presentationer/cadec-2015-java8.pdf · • Using an anonymous inner class for a callback: JAVA 8 LAMBDA EXPRESSIONS 7 asyncHttpClient.execute(url,!

•  Separate the knowledge of the object model to a separate function - That takes three functions as arguments…

LET’S TAKE ONE MORE STEP INTO THE FUNCTIONAL WORLD…

24

private List<Product> getProducts( ! Predicate <Order> orderFilter, ! Predicate <Product> productFilter, ! Comparator<Product> productComparator) { !! return getOrders().stream() ! .filter (orderFilter) ! .flatMap (o -> o.getOrderLines().stream()) ! .map (ol -> ol.getProduct()) ! .filter (productFilter) ! .distinct() ! .sorted (productComparator) ! .collect (Collectors.toList()); !} !

Page 25: CADEC 2015 - JAVA 8beta.callistaenterprise.se/assets/presentationer/cadec-2015-java8.pdf · • Using an anonymous inner class for a callback: JAVA 8 LAMBDA EXPRESSIONS 7 asyncHttpClient.execute(url,!

•  Example #1

•  •  Example #2

FUNCTIONAL PROGRAMMING TAKE 2

25

public List<Product> getProductsByDateAndCategoryOrderByWeight( ! LocalDate minDate, LocalDate maxDate, String category) { !! return getProducts( ! o -> o.getOrderDate().isAfter(minDate) && o.getOrderDate().isBefore(maxDate), ! p -> p.getCategory().equals(category), ! (p1, p2) -> (p1.getWeight() < p2.getWeight()) ? -1 : 1); !} !

public List<Product> getProductsByOrderValueAndWeightOrderByProductId( ! int minOrderValue, int maxOrderValue, int minProductWeight, int maxProductWeight) { !! return getProducts( ! o -> minOrderValue <= o.getOrderValue() && o.getOrderValue() <= maxOrderValue, ! p -> minProductWeight <= p.getWeight() && p.getWeight() <= maxProductWeight, ! (p1, p2) -> ((p1.getId() < p2.getId()) ? -1 : 1)); !} !

Page 26: CADEC 2015 - JAVA 8beta.callistaenterprise.se/assets/presentationer/cadec-2015-java8.pdf · • Using an anonymous inner class for a callback: JAVA 8 LAMBDA EXPRESSIONS 7 asyncHttpClient.execute(url,!

•  Also see http://callistaenterprise.se/blogg/teknik/2014/12/29/trying-out-functional-programming-in-Java8/

INTRODUCTION TO FUNCTIONAL PROGRAMMING

26

Page 27: CADEC 2015 - JAVA 8beta.callistaenterprise.se/assets/presentationer/cadec-2015-java8.pdf · • Using an anonymous inner class for a callback: JAVA 8 LAMBDA EXPRESSIONS 7 asyncHttpClient.execute(url,!

•  Start use Java 8 now!

•  Look for areas where you can benefit from the new features -  Start at small scale and widen the usage

once proven within your organization…

•  Verify that your 3PP’s support Java 8

SUMMARY

27