Project Lambda: Evolution of Java

673 views
566 views

Published on

Java 8 features that contain lambda expressions, stream api, optional type, default methods, nashorn javascript engine, metaspace

Published in: Technology, News & Politics
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
673
On SlideShare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
13
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Project Lambda: Evolution of Java

  1. 1. Project Lambda: Evolution of Java Can Pekdemir
  2. 2. “I would say, for most Java developers, it’s revolutionary. For polyglot programmers, it’s evolutionary”. Adam Bien - author of Real World Java EE Patterns
  3. 3. Agenda • Programming paradigms • Rise of functional programming • Lambda expressions • Functional Interface • Stream API • Other exciting Java 8 features
  4. 4. Programming Paradigms • Main programming paradigms • Imperative programming • Functional programming • Logic programming • Object-Oriented Programming?
  5. 5. Imperative Programming • Ideas of Von Neumann architecture digital hardware technology • First do this and next do that • Concentrates on how • Mutable variables • Assignments, control structures if-then-else, loops, etc.
  6. 6. Imperative Programming Total of discounted prices by then which are greater than 20. BigDecimal totalOfDiscountedPrices = BigDecimal.ZERO; for(BigDecimal price : prices) { if(price.compareTo(BigDecimal.valueOf(20)) > 0) totalOfDiscountedPrices = totalOfDiscountedPrices.add(price.multiply(BigDecimal.valueOf(0.9))); } System.out.println("Total of discounted prices: “ + totalOfDiscountedPrices);
  7. 7. Functional Programming • Mathematics and the theory of functions • John Backus:”Can programming be liberated from the von Neumann Style?” • Functions are first class citizens. • Functions can be defined anywhere, inside other functions. • Functions can be passed as argument. • Typically avoids mutable state. • What we want rather than how to do it.
  8. 8. Functional Programming final BigDecimal totalOfDiscountedPrices = prices.stream() .filter(price -> price.compareTo(BigDecimal.valueOf(20)) > 0) .map(price -> price.multiply(BigDecimal.valueOf(0.9))) .reduce(BigDecimal.ZERO, BigDecimal::add); Declarative style: expressions over statements.
  9. 9. Executionin the Kingdomof Nouns button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { System.out.println("hi " + name); }}); StateManager.getConsiderationSetter("Noun Oriented Thinking", State.HARMFUL).run(); Steve Yegge http://steve-yegge.blogspot.com.tr/2006/03/execution-in- kingdom-of-nouns.html
  10. 10. The Difference “OO makes code understandable by encapsulating moving parts. FP makes code understandable by minimizing moving parts.” Michael Feathers, author of “Working with legacy code”
  11. 11. Functional Programming Rises • The rise of multicore CPUs and big data. • Need for parallel programming with immutable data. • Declarative programming • Less clutter code
  12. 12. Java Evolution • Lack of abstracting over behaviour, not just data • Parallelism should be free, confusing thread api • Need for lazy evaluation over data
  13. 13. Behaviour Abstraction • First requirement: filter green apples public static List<Apple> filterGreenApples(List<Apple> inventory){ List<Apple> result = new ArrayList<>(); for (Apple apple: inventory){ if ("green".equals(apple.getColor())) { result.add(apple); } } return result; } What if they want to according to “red”!
  14. 14. Behaviour Abstraction • Abstracting over color public static List<Apple> filterApplesByColour(List<Apple> inventory, String color) { List<Apple> result = new ArrayList<>(); for (Apple apple: inventory){ if ( apple.getColor().equals(color) ) { result.add(apple); } } return result; } - What if they want to filter according to weight!
  15. 15. Refactoring? public static List<Apple> filterApples(List<Apple> inventory, String color, int weight, boolean flag) { List<Apple> result = new ArrayList<>(); for (Apple apple: inventory){ if ( (flag && apple.getColor().equals(color)) || (!flag && apple.getWeight() > weight) ){ result.add(apple); } } return result; } List<Apple> greenApples = filterApples(inventory, "green", 0, true); List<Apple> heavyApples = filterApples(inventory, "", 150, false);
  16. 16. Parameterize Behaviour ApplePredicate encapsulates a strategy for selecting an apple public interface ApplePredicate{ boolean test (Apple apple); } public class AppleWeightPredicate implements ApplePredicate{ public boolean test(Apple apple){ return apple.getWeight() > 150; } } public class AppleColorPredicate implements ApplePredicate{ public boolean test(Apple apple){ return "green".equals(apple.getColor()); } }
  17. 17. Filtering by an Abstract Criterion public static List<Apple> filterApples(List<Apple> inventory, ApplePredicate p){ List<Apple> result = new ArrayList<>(); for(Apple apple: inventory){ if(p.test(apple)){ result.add(apple); } } return result; }
  18. 18. Filter with Anonymous Class List<Apple> redApples = filterApples(inventory, new ApplePredicate() { public boolean test(Apple apple){ return "red".equals(a.getColor()); } }); - Very bulky and confusing to use.
  19. 19. Filter Using Lambda Expression filterApples(inventory, (Apple apple) -> "red".equals(apple.getColor())); filterApples(inventory, (Apple apple) -> "green".equals(apple.getColor())); filterApples(inventory, (Apple apple) -> apple.getWeight() > 150);
  20. 20. Refactor Design with Generics public static <T> List<T> filter(List<T> list, Predicate<T> p){ List<T> result = new ArrayList<>(); for(T e: list){ if(p.test(e)){ result.add(e); }} return result; } List<Apple> redApples = filter(inventory, (Apple apple) -> "red".equals(apple.getColor())); List<Integer> evenNumbers = filter(numbers, (Integer i) -> i % 2 == 0);
  21. 21. Real World Examples Anonymous inner class inventory.sort(new Comparator<Apple>() { public int compare(Apple a1, Apple a2){ return a1.getWeight().compareTo(a2.getWeight()); } }); Lambda inventory.sort((Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight())); Anonymous inner class Thread t = new Thread(new Runnable() { public void run(){ System.out.println("Hello world"); } }); Lambda Thread t = new Thread(() -> System.out.println("Hello world"));
  22. 22. Lambda Expressions • Anonymous function • Doesn’t have a name • Has a list of parameters, a body, a return type (List<String> list) -> list.isEmpty() () -> new Apple(10) (Apple a) -> System.out.println(a.getWeight()) (String s) -> s.length() (int a, int b) -> a * b (Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight())
  23. 23. Functional Interface • Lambdas are supported by functional interface • An interface with single abstract method @FunctionalInterface public interface Predicate<T> { boolean test(T t); }
  24. 24. java.util.function • Predefined Functional Interfaces • Function<T,R> : Takes an object of type T and returns R. • Supplier<T> : Just returns an object of type T. • Predicate<T> : returns a boolean value based on type T. • Consumer<T> : performs an action with given type T.
  25. 25. Predicate • Defines an abstract method test Predicate<String> nonEmptyStringPredicate = (String s) -> !s.isEmpty(); List<String> nonEmpty = filter(listOfStrings, nonEmptyStringPredicate);
  26. 26. Consumer • Perform some operation on type T public interface Consumer<T>{ public void accept(T t); } public static <T> void forEach(List<T> list, Consumer<T> c){ for(T i: list){ c.accept(i); } } forEach(Arrays.asList(1,2,3,4,5),(Integer i) -> System.out.println(i));
  27. 27. Function • Defines an abstract method named apply, takes an argument T and returns of type R. public interface Function<T, R>{ public R apply(T t); } public static <T, R> List<R> map(List<T> list, Function<T, R> f) { List<R> result = new ArrayList<>(); for(T s: list){ result.add(f.apply(s)); } return result; } List<Integer> l = map(Arrays.asList("lambdas","in","action"), (String s) -> s.length());
  28. 28. Functional Interface for Primitives • Performance saving from autoboxing with primitive ones. public interface IntPredicate{ public boolean test(int t); } IntPredicate evenNumbers = (int i) -> i % 2 == 0; evenNumbers.test(1000); // true (no boxing) Predicate<Integer> oddNumbers = (Integer i) -> i % 2 == 1; oddNumbers.test(1000); // false (boxing)
  29. 29. Type Interference • Deduce appropriate signature and target type List<Apple> greenApples = filter(inventory, (Apple a) -> "green".equals(a.getColor())); List<Apple> greenApples = filter(inventory, a -> "green".equals(a.getColor())); Comparator<Apple> c =(Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight()); Comparator<Apple> c = (a1, a2) -> a1.getWeight().compareTo(a2.getWeight());
  30. 30. Capturing Variables within a Lambda • The variable should be captured in lambda must be final or “effectively final”. int portNumber = 1337; //error portNumber = 31338; Runnable r = () → System.out.println(portNumber);
  31. 31. Method References • Another syntax for lambda expressions Lambda Method reference equivalent (Apple a)-> a.getWeight() Apple::getWeight ()->Thread.currentThread.dumpStack() Thread.currentThread()::dumpStack (String s) -> System.out.println(s) System.out::println
  32. 32. Stream API • A sequence of elements from a source that supports aggregate operations. • Stream doesn’t hold all data • Lazily constructed collections • Uses internal iterations • Supports parallelism easily. • java.util.stream
  33. 33. Filter • Acceps a predicate to filter stringCollection .stream() .filter((s) -> s.startsWith("a")) .forEach(System.out::println);
  34. 34. Sorted • Sorted in natural order unless you pass a custom Comparator. stringCollection .stream() .sorted() .filter((s) -> s.startsWith("a")) .forEach(System.out::println); //list interface sort method inventory.sort((a1, a2) -> a1.getWeight().compareTo(a2.getWeight()));//sort by weight
  35. 35. Map • Convert each element into another object. • Uses Function interface stringCollection .stream() .map(String::toUpperCase) .sorted((a, b) -> b.compareTo(a)) .forEach(System.out::println);
  36. 36. Reduce • Perform a reduction on the elements of the stream List<Integer> numbers = Arrays.asList(3,4,5,1,2); int sum = numbers.stream().reduce(0, (a, b) -> a + b); int sum2 = numbers.stream().reduce(0, Integer::sum); int max = numbers.stream().reduce(0, (a, b) -> Integer.max(a, b));
  37. 37. Match • returns a boolean • boolean anyStartsWithA = stringCollection .stream() .anyMatch((s) -> s.startsWith("a")); • anyMatch, allMatch, noneMatch
  38. 38. Other Useful Methods • distinct > returns a stream of distinct elements • peek > support debugging of elements • limit > returns a stream of elements with maxSize • skip > returns a stream of elements after discarding the first number of elements of stream. • min, max, count • forEach, collect(toList), findFirst, findAny, of • groupingBy, partitioningBy
  39. 39. Lazy Evaluation • Lazy intermediate operations: filter, sorted, map, • Terminal operations: match, count, reduce, collect List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8); List<Integer> twoEvenSquares = numbers .stream() .filter(n -> n% 2 == 0) .map(n -> n * n) .limit(2) .collect(toList()); System.out.println(twoEvenSquares); // [ 4, 16]
  40. 40. Parallelism
  41. 41. Parallel Stream • Just use parallelStream method • We should be careful about the collection size for performance List<Apple> greenApples = inventory.parallelStream() .filter(a -> "green".equals(a.getColor())) .sorted() .collect(toList());
  42. 42. Null Reference Problem • “I call it my billion-dollar mistake. simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years.” Tony Hoare – developed quick sort, ALGOL
  43. 43. Optional Type Optional<String> reduced = stringCollection .stream() .sorted() .reduce((s1, s2) -> s1 + "#" + s2); reduced.ifPresent(System.out::println);
  44. 44. Optional Type Optional<String> optional = Optional.of("test"); optional.isPresent(); // true optional.get(); // "test" optional.orElse("fallback"); // "test” optional.ifPresent((s) -> System.out.println(s.charAt(0))); // "t"
  45. 45. Default Methods • Also known as virtual extension methods • Adds methods to interfaces with implementation • Mainly aimed for backward compatibility • Multiple inheritance?, difference from abstract class? interface Iterable<T> { default void forEach(Consumer<? super T> action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } } }
  46. 46. New Date API • Under the package java.time • Looks like Joda-Time library • Immutable classes LocalTime now1 = LocalTime.now(); LocalTime now2 = LocalTime.now(); System.out.println(now1.isBefore(now2)); // false LocalDate today = LocalDate.now(); //immutable LocalDate tomorrow = today.plusDays(1); LocalDate yesterday = tomorrow.minusDays(2); LocalDateTime localDateTime = LocalDateTime.now();
  47. 47. Nashorn Javascript Engine • replaces the old Rhino Javascript engine • competes with Google V8(powers Chrome and Node.js) • can be executed command-line with jjs tool or programmatically • javascript functions can be called from java side
  48. 48. Nashorn Javascript Engine var fun1 = function(name) { print('Hi there from Javascript, ' + name); return "greetings from javascript"; }; ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn"); engine.eval(new FileReader("script.js")); Invocable invocable = (Invocable) engine; Object result = invocable.invokeFunction("fun1", ”Liu Kang");
  49. 49. Metaspace • A new memory space • Permgen space completely removed • Allocations for the class metadata are now allocated out of native memory • A new flag is available (MaxMetaspaceSize)
  50. 50. Questions?
  51. 51. References • https://github.com/java8/Java8InAction • http://winterbe.com/posts/2014/03/16/java-8-tutorial/ • http://blog.informatech.cr/2013/04/10/java-optional-objects/ • http://viralpatel.net/blogs/java-8-default-methods-tutorial/ • http://steve-yegge.blogspot.com.tr/2006/03/execution-in-kingdom-of-nouns.html • http://en.wikipedia.org/wiki/Tony_Hoare • http://winterbe.com/posts/2014/04/05/java8-nashorn-tutorial/ • http://java.dzone.com/articles/java-8-permgen-metaspace • Subramaniam, Venkat. (2014) Functional Programming in Java: Harnessing the Power Of Java 8 Lambda Expressions • Warburton, Richard. (2014) Java 8 Lambdas: Pragmatic Functional Programming • Urma, Raoul-Gabriel. (2014) Java 8 in Action: Lambdas, Streams and Functional-style Programming

×