Slide 1

Slide 1 text

Java 8 Latest Language Additions

Slide 2

Slide 2 text

Dmitry Buzdin [email protected] @buzdin

Slide 3

Slide 3 text

Java 8 released on ! 18th of March 2014 https://jdk8.java.net/download.html DOWNLOAD

Slide 4

Slide 4 text

Significant Changes • Lambda Expressions • Method References • Default Methods • Type Annotations • Streams API http://www.oracle.com/technetwork/java/javase/8-whats-new-2157071.html

Slide 5

Slide 5 text

Lambda Expressions http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html

Slide 6

Slide 6 text

Before Java 8 • Everything is a class (except primitives) • Class is a “heavyweight” construct • Composition is hard

Slide 7

Slide 7 text

Use Cases • Reusable composite constructs needed: • GUI Listeners • Command pattern • Event processing • Asynchronous programming

Slide 8

Slide 8 text

UI Listener addClickListener(ClickListener listener); ! public interface ClickListener { void onClick(Widget sender) }

Slide 9

Slide 9 text

button.addClickListener(new ClickListener() { public void onClick(Widget sender) { processData(sender.getText()); reportData(sender.getText()); logResults(); } }); Existing Solution Anonymous Class

Slide 10

Slide 10 text

Async executeAsync(“param”, new Callback() { @Override onSuccess(String result1) { executeAsync(result1, new Callback()) { @Override onSuccess(Object result2) { System.out.println(result); } } } })

Slide 11

Slide 11 text

Anonymous Classes • Hard to read • New objects are created in heap • Compiler creates additional class files

Slide 12

Slide 12 text

Is there something better?

Slide 13

Slide 13 text

Lambda Expression “Function, defined and called without being bound to identifier” Relates to Functional Programming

Slide 14

Slide 14 text

In Other Languages Scala Groovy Ruby Python (x: Int, y: Int) => x + y { int x, int y -> x + y } lambda {|x, y| x + y} lambda x,y: return x * y function (x,y) {return x * y} JavaScript (int x, int y) => x + y C#

Slide 15

Slide 15 text

Current Java Approach Emulate Lambdas with smart libraries

Slide 16

Slide 16 text

LambdaJ List buyersSortedByAges = sort( extract( select(sales, having(on(Sale.class).getValue(), greaterThan(50000))) ), on(Sale.class).getBuyer() ), on(Person.class).getAge()); https://code.google.com/p/lambdaj/

Slide 17

Slide 17 text

Guava List integers = Lists.newArrayList(1, 2, 3); Iterables.filter(integers, new Predicate() { @Override public boolean apply(Integer input) { return input % 2 == 0; } }); https://code.google.com/p/guava-libraries/

Slide 18

Slide 18 text

Time to learn Scala Java is not functional No Lambdas make me sad Welcome!

Slide 19

Slide 19 text

The Question for Java 8 • How to add Lambdas but • remain Java • be backward compatible • reuse existing libraries

Slide 20

Slide 20 text

Lambdas in Java 8 (Integer x, Integer y) -> x + y (Integer x, Integer y) -> { r = x + y; System.out.println(r); return r; }

Slide 21

Slide 21 text

Oppa Lambda Style! button.addClickListener((sender) -> { processData(sender.getText()); reportData(sender.getText()); logResults(); });

Slide 22

Slide 22 text

Async executeAsync(“param”, (result1) -> executeAsync(result1, (result2) -> System.out.println(result2)));

Slide 23

Slide 23 text

Much ! Better! Now!

Slide 24

Slide 24 text

Where can be used? • Lambdas can be used with Functional Interfaces • Functional Interface - interface with one abstract method • Existing interfaces can be reused if they satisfy the rules

Slide 25

Slide 25 text

Functional Interface @FunctionalInterface public interface ClickHandler { ! void onClick(Widget widget); ! // Gives compile time error void onDoubleClick(Widget widget); } java: Unexpected @FunctionalInterface annotation lv.jug.java8.Listener is not a functional interface multiple non-overriding abstract methods found in interface lv.jug.java8.Listener

Slide 26

Slide 26 text

Existing JDK FIs Comparator { boolean compare(T x, T y); } Runnable { void run(); } Callable { T call(); } PropertyChangeListener { void propertyChange(PropertyChangeEvent evt) }

Slide 27

Slide 27 text

New JDK FIs java.util.function package contains 44 new functional interfaces Consumer, Function, Predicate, Supplier, Operator and versions for all primitives

Slide 28

Slide 28 text

java.util.function • Predicate: A property of the object passed as argument • Consumer: An action to be performed with the object passed as argument • Function: Transform a T to a U • Supplier: Provide an instance of a T (such as a factory) • UnaryOperator: A unary operator from T -> T • BinaryOperator: A binary operator from (T, T) -> T

Slide 29

Slide 29 text

Guava and Lambdas https://code.google.com/p/guava-libraries/wiki/FunctionalExplained ArrayList integers = Lists.newArrayList(1, 2, 3); Iterables.filter(integers, (i) -> i % 2 == 0); Guava has its own Predicate, Supplier, Function etc. Can be used with Lambda syntax

Slide 30

Slide 30 text

Scope int f1 = 0; int f2 = 0; ! void lambdaScope(final int p1, String p2) { int i1 = 1; i1++; int i2 = 2; final int i3 = 3; f2 = 4; execute(() -> { // ? }); } this.f1; this.f2; p1; p2; i2; i3

Slide 31

Slide 31 text

Type Inference List list = new ArrayList<>(); ! Collections.sort(list, (Integer x, Integer y) -> x - y); Collections.sort(list, (x, y) -> x - y);

Slide 32

Slide 32 text

Compiling Lambdas http://www.takipiblog.com/2014/01/16/compiling-lambda-expressions-scala-vs-java-8/ • Lambdas are compiled as invoke dynamic calls • No additional class files created • No new objects created

Slide 33

Slide 33 text

So what? • Finally, Java is not worse than Ruby! • Less coding • Static type compiler checks

Slide 34

Slide 34 text

What to do with this? void someMethod() { lambda1((arg) -> process(arg)); lambda2((arg) -> process(arg)); lambda3((arg) -> process(arg)); } Can we simplify this even further?

Slide 35

Slide 35 text

No content

Slide 36

Slide 36 text

Method References http://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html

Slide 37

Slide 37 text

Method Reference MyCoolClass::method There are four different types of method references object::method Like C method pointer, but safer

Slide 38

Slide 38 text

Static Method public static int compare(Integer a, Integer b); ! Arrays.sort(array, new Comparator() { @Override public int compare(Integer a, Integer b) { return Util.compare(a, b); } }); Arrays.sort(array, Util::compare);

Slide 39

Slide 39 text

Instance Method MyClass object = new MyClass(); ! Arrays.sort(array, new Comparator() { @Override public int compare(Integer a, Integer b) { return object.reverse(a, b); } }); Arrays.sort(array, object::reverse);

Slide 40

Slide 40 text

Arbitrary Object Arrays.sort(array, new Comparator() { @Override public int compare(String a, String b) { return a.compareToIgnoreCase(b); } }); Arrays.sort(array, String::compareToIgnoreCase);

Slide 41

Slide 41 text

Constructor List list1 = createNewObject( new Supplier() { @Override public List get() { return new ArrayList<>(); } }); List list2 = createNewObject(ArrayList::new);

Slide 42

Slide 42 text

Async with References executeAsync("param", (result1) -> executeAsync(result1, System.out::println));

Slide 43

Slide 43 text

New API Possibilities http://benjiweber.co.uk/blog/2013/12/28/typesafe-database-interaction-with-java-8/ Optional person = from(Person.class) .where(Person::getFirstName) .like("%ji") .and(Person::getLastName) .equalTo("weber") .select(personMapper, connectionFactory::openConnection);

Slide 44

Slide 44 text

Recap • It is possible to reference existing methods instead of writing lambda expressions • Reuse of existing pre Java 8 code • Different type of references

Slide 45

Slide 45 text

Default Methods http://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html

Slide 46

Slide 46 text

Java 7 Model • Single inheritance • Multiple interfaces • No method implementations on interface • All methods on interfaces are abstract

Slide 47

Slide 47 text

Default Methods public interface MyInterface { ! void apply(); ! default void apply2() { // do some work } ! }

Slide 48

Slide 48 text

Extending Interfaces public class Klass implements MyInterface { @Override void apply() { ... } } ! Klass k = new Klass(); klass.apply(); klass.apply2();

Slide 49

Slide 49 text

Multiple Interfaces public class Klass implements CanWalk, CanFly, CanSwim, CanDrive { ... } ! Klass k = new Klass(); klass.walk(); klass.eat(); klass.fly();

Slide 50

Slide 50 text

Wait, ! is this not ! multiple ! inheritance?

Slide 51

Slide 51 text

Not really, there is no state in interfaces.

Slide 52

Slide 52 text

Potential Use • Library API evolution support • Utility methods shipped with interface • Default method implementations (no more dummy adapters) • Could be used as Traits/Mixins with some hacks

Slide 53

Slide 53 text

Evil Traits public interface CanWalk { default void walk() { ((Human) this).leftLeg(); ((Human) this).rightLeg(); } } class Human implements CanWalk, CanSwim public interface CanSwim { default void swim() { ((Human) this).leftHand(); ((Human) this).rightHand(); } }

Slide 54

Slide 54 text

Static Methods public static interface MyInterface { ! public static String wrap(String s) { return "{" + s + "}"; } ! void apply(); ! } Nice for utility methods

Slide 55

Slide 55 text

Factory + Interface • Could be finally combined • Shared functions on the interface • Better Encapsulation

Slide 56

Slide 56 text

Factory on Interface public interface Gadget { public static Gadget create(String id) { return new GadgetImpl(); } ! void start(); } ! Gadget gadget = Gadget.create(“x”); gadget.start();

Slide 57

Slide 57 text

All Together StringProcessor p = new StringProcessor(" sdfsdf "); Function one = String::trim; Function two = one.andThen( (s) -> s.replaceAll("s", “") ); String result = p.process(two); System.out.println(result);

Slide 58

Slide 58 text

Other Changes

Slide 59

Slide 59 text

Type Annotations http://docs.oracle.com/javase/tutorial/java/annotations/type_annotations.html @NonNull String str; Annotations anywhere you use a type. Pretty cool for frameworks and tools.

Slide 60

Slide 60 text

Repeating Annotations http://docs.oracle.com/javase/tutorial/java/annotations/repeating.html @Schedule(dayOfMonth="last") @Schedule(dayOfWeek="Fri", hour="23") public void doPeriodicCleanup() { ... } @Repeatable(Schedules.class) public @interface Schedule { ... }

Slide 61

Slide 61 text

Method Parameter Reflection @Path("/users/{username}") public class UserResource { @GET @Produces("text/xml") public String getUser( @PathParam("username") String username) { ... } } Before Java 8 impossible to get this name in runtime

Slide 62

Slide 62 text

Memory Model Change

Slide 63

Slide 63 text

Permanent Generation • Permanent generation was removed • New metaspace area in native memory • No more OutOfMemory in PermGen • PermSize parameter does nothing http://java.dzone.com/articles/java-8-permgen-metaspace

Slide 64

Slide 64 text

Now why should I care?

Slide 65

Slide 65 text

Java Support http://www.oracle.com/technetwork/java/eol-135779.html

Slide 66

Slide 66 text

Overall Impression “Java 8 has really done a very elegant job” ““This is the first time we have done a carefully coordinated co-evolution of the JVM, the language, and the libraries all together – and the results still feel like Java,”” “Java SE 8 lands with Lambda expressions making coding easier for multi-core processors"

Slide 67

Slide 67 text

Effect on Libraries • Util function libraries • Method references • Reflection names of parameters • Static and default methods • Standard interfaces in JDK (e.g. Predicate) • Bytecode incompatibility (cyglib, asm)

Slide 68

Slide 68 text

This slide was intentionally left blank