Project Lambda: Evolution of Java
-
Upload
can-pekdemir -
Category
Technology
-
view
420 -
download
3
description
Transcript of Project Lambda: Evolution of Java
![Page 1: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/1.jpg)
Project Lambda: Evolution of JavaCan Pekdemir
![Page 2: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/2.jpg)
“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
![Page 3: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/3.jpg)
Agenda• Programming paradigms• Rise of functional programming• Lambda expressions• Functional Interface• Stream API• Other exciting Java 8 features
![Page 4: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/4.jpg)
Programming Paradigms• Main programming paradigms• Imperative programming• Functional programming• Logic programming• Object-Oriented Programming?
![Page 5: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/5.jpg)
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.
![Page 6: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/6.jpg)
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);
![Page 7: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/7.jpg)
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.
![Page 8: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/8.jpg)
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.
![Page 9: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/9.jpg)
Execution in the Kingdom of Nouns
button.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent event) {
System.out.println("hi " + name);}});
StateManager.getConsiderationSetter("Noun Oriented Thinking", State.HARMFUL).run();
Steve Yeggehttp://steve-yegge.blogspot.com.tr/2006/03/execution-in-kingdom-of-nouns.html
![Page 10: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/10.jpg)
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”
![Page 11: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/11.jpg)
Functional Programming Rises
• The rise of multicore CPUs and big data.• Need for parallel programming with immutable data.• Declarative programming• Less clutter code
![Page 12: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/12.jpg)
Java Evolution• Lack of abstracting over behaviour, not just data• Parallelism should be free, confusing thread api• Need for lazy evaluation over data
![Page 13: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/13.jpg)
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”!
![Page 14: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/14.jpg)
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!
![Page 15: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/15.jpg)
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);
![Page 16: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/16.jpg)
Parameterize BehaviourApplePredicate 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());} }
![Page 17: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/17.jpg)
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;}
![Page 18: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/18.jpg)
Filter with Anonymous ClassList<Apple> redApples = filterApples(inventory,
new ApplePredicate() { public boolean test(Apple apple){
return "red".equals(a.getColor()); }});
- Very bulky and confusing to use.
![Page 19: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/19.jpg)
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);
![Page 20: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/20.jpg)
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);
![Page 21: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/21.jpg)
Real World ExamplesAnonymous inner classinventory.sort(new Comparator<Apple>() { public int compare(Apple a1, Apple a2){
return a1.getWeight().compareTo(a2.getWeight()); }});Lambdainventory.sort((Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight()));
Anonymous inner classThread t = new Thread(new Runnable() { public void run(){
System.out.println("Hello world"); }});LambdaThread t = new Thread(() -> System.out.println("Hello world"));
![Page 22: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/22.jpg)
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())
![Page 23: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/23.jpg)
Functional Interface• Lambdas are supported by functional interface• An interface with single abstract method
@FunctionalInterfacepublic interface Predicate<T> {
boolean test(T t);}
![Page 24: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/24.jpg)
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.
![Page 25: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/25.jpg)
Predicate• Defines an abstract method test
Predicate<String> nonEmptyStringPredicate = (String s) -> !s.isEmpty();
List<String> nonEmpty = filter(listOfStrings, nonEmptyStringPredicate);
![Page 26: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/26.jpg)
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));
![Page 27: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/27.jpg)
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());
![Page 28: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/28.jpg)
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)
![Page 29: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/29.jpg)
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());
![Page 30: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/30.jpg)
Capturing Variables within a Lambda
• The variable should be captured in lambda must be final or “effectively final”.
int portNumber = 1337;//errorportNumber = 31338;Runnable r = () → System.out.println(portNumber);
![Page 31: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/31.jpg)
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
![Page 32: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/32.jpg)
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
![Page 33: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/33.jpg)
Filter• Acceps a predicate to filter
stringCollection .stream() .filter((s) -> s.startsWith("a")) .forEach(System.out::println);
![Page 34: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/34.jpg)
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
![Page 35: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/35.jpg)
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);
![Page 36: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/36.jpg)
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));
![Page 37: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/37.jpg)
Match• returns a boolean
• boolean anyStartsWithA = stringCollection .stream() .anyMatch((s) -> s.startsWith("a"));
• anyMatch, allMatch, noneMatch
![Page 38: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/38.jpg)
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
![Page 39: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/39.jpg)
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]
![Page 40: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/40.jpg)
Parallelism
![Page 41: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/41.jpg)
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());
![Page 42: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/42.jpg)
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
![Page 43: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/43.jpg)
Optional TypeOptional<String> reduced = stringCollection
.stream() .sorted() .reduce((s1, s2) -> s1 + "#" + s2);
reduced.ifPresent(System.out::println);
![Page 44: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/44.jpg)
Optional TypeOptional<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"
![Page 45: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/45.jpg)
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); } }}
![Page 46: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/46.jpg)
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)); // falseLocalDate today = LocalDate.now(); //immutableLocalDate tomorrow = today.plusDays(1);LocalDate yesterday = tomorrow.minusDays(2);LocalDateTime localDateTime = LocalDateTime.now();
![Page 47: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/47.jpg)
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
![Page 48: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/48.jpg)
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");
![Page 49: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/49.jpg)
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)
![Page 50: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/50.jpg)
Questions?
![Page 51: Project Lambda: Evolution of Java](https://reader035.fdocuments.net/reader035/viewer/2022062405/554f380cb4c905cd048b4e94/html5/thumbnails/51.jpg)
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