Java 8 Lambda Expression Sang Shin JPassion.com “Code with Passion!”

1

Topics • • • • • • • •

What is and Why Lambda Expression (or simply Lambda)? Lambda implementation in Java What is Functional interface? Lambda expression syntax in Java 8 Method references Java 8 provided Functional Interface definitions Composition Effectively final local variables

2

What is and Why Lambda Expression?

What is Lambda Expression? • A formal system for expressing “computational behavior” (or “parameterizing behavior”) > Through functions • Functions are first-class citizens > Function can be assigned to a variable > Function can be passed to a method as an argument > Function can be returned • Many modern programming languages supports Lambda expression > JavaScript, List, Scheme > Ruby, Scala, Clojure • Java 8 now supports Lambda expression > Biggest language change since Generics of Java 1.5 4

Why Lambda? • Let you declare what to do, not how to do it > Cleaner, more concise code > High productivity, flexible, “fluent” style programming is possible

• Promotes immutability > Less concurrency issues

• Enables parallel programming & lazy evaluation > Higher performance

• Forms the basis of functional programming paradigm > When functional programming is used, many set of problems are

easier to solve, and results in cleaner code

• Richer collection APIs possible 5

Java 8 Implementation of Lambda Expression

Concept vs. Implementation • Lambda expression is a concept > Different programming languages have different implementations of Lambda expression • You, as a Java developer, need to learn > General concept of Lambda expression > How Java 8 implements Lambda expression

7

Java 8 Implementation of Lambda • In Java 8, a Lambda expression is implemented essentially as an anonymous function > A Lambda expression is considered as a instance of a functional interface (an interface with a single abstract method) > The type of Lambda expression is that functional interface • There is no native “function” type (unlike in other languages), however, in Java 8 Lambda implementation > This is a deliberate decision by Java 8 Lambda designers

8

Usage Areas of Lambda in Java Programs • • • • • •

Anonymous inner class Event handling Iteration over list Parallel processing of collection elements at the API level Functional programming Streams

9

What is Functional Interface?

What is a Functional Interface? • A regular Java interface with a single (abstract) method > It is common in Java programs > Sometimes called Single Abstract Method (SAM)

• Names of interface and method are irrelevant > What matters is the arguments and the body of the method

11

What is a Functional Interface? • In fact, even previous Java (Java 7 and below) has several functional interfaces already // Runnable interface public interface Runnable { public abstract void run(); } // Comparable interface public interface Comparable { public int compareTo(T o); }

12

@FunctionalInterface Annotation • When used, Java 8 compiler produces an error if the interface has more than one method @FunctionalInterface public interface MyInterface { public String myMethod(); } // Generates Invalid @FunctionalInterface error @FunctionalInterface public interface MyInterface { public String myMethod(); public String myMethod2(); } 13

Backward Compatibility • Any interface with a single method is considered as a functional interface by Java 8 • Java 8 Lambda works with old libraries that use functional interfaces without any need to recompile or modification

14

Where to use Lambda Expression in Java? • Concept > You use Lambda expression where a functional behavior is required • Java > You can use Lambda expression in any place where the functional interface type is expected • Examples > You can assign a lambda expression to a variable whose type is functional interface > You can pass a lambda expression to a method as an argument whose type is a functional interface

15

Example #1 • Let's say we have a functional interface @FunctionalInterface public interface Calculator { int calculate(int x, int y); }

• A variable whose type is a functional interface can be assigned with a lambda expression Calculator multiply = (x,y) -> x*y; Calculator divide = (x,y) ->x/y; int product = multiply.calculate(50,10); int quotient = divide.calculate(50,10);

16

Example #2 • Let's say we have a functional interface (same as in prev. slide) @FunctionalInterface public interface Calculator { int calculate(int x, int y); }

• Types of arguments are functional interface public static void myMethod(Calculator m, Calculator d){ int product = m.calculate(60, 10); int quotient = d.calculate(60, 10); System.out.println("product = " + product + " quotient = " + quotient); }

• Pass lambda expression as arguments myMethod((x,y)->x+y, (x,y)->x/y); 17

Lab: Exercise 1: Functional Interface 1621_java8_lambda_expression.zip

18

Anonymous Inner Class Replaced by Lambda

Anonymous Inner Class and Lambda • Given that typical usage of anonymous inner class is an example of an argument whose type is a functional interface, you can now replace it with Lambda expression > In fact, anonymous inner class is used as a kludge solution for passing a functional behavior (before Lambda is available) > But anonymous inner class is verbose, hard to optimize, etc • The current code what uses Anonymous Inner class can be greatly simplified through the usage of Lambda > Just take the arguments and code block with following Lambda syntax removing everything else (arguments) -> {code block}

20

Example #1 • Anonymous Runnable replaced by Lambda // Anonymous Runnable Runnable r1 = new Runnable() { @Override public void run() { System.out.println("Hello world one!"); } }; // Lambda Runnable Runnable r2 = () -> System.out.println("Hello world two!"); // Run them! r1.run(); r2.run(); 21

Example #2 • Anonymous ActionListener replaced by Lambda // Anonymous ActionListener testButton1.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println("Click Detected by Anonymous Listener"); } }); // Lambda ActionListener testButton2.addActionListener(e -> System.out.println("Click Detected by Lambda Listner"));

22

Lab: Exercise 2: Rewriting Anonymous Inner Class with Lambda Expression 1621_java8_lambda_expression.zip

23

Lambda Expression Syntax in Java

Lambda Expression Syntax • General syntax > (argument list) -> { code block}

• Syntax can be simplified in the following ways > Type inferencing for the arguments > Omitting parentheses for a single argument > Implied return when a body has only a single expression and no need

to have { }

25

Type inferencing for the arguments • Types in argument list can be usually omitted > Java compiler already knows the types of the arguments from the

single method signature of the functional interface

// Instead of this (String myArg1, Integer myArg2) → {... } // You can do this because types can be inferred (myArg1, myArg2) → {… }

26

Single argument with no () • If there is a single argument, parens () are optional // Instead of this (myArg1) → {... } // You can do this myArg1 → {… }

27

When body has only an expression • When the code block has only an expression, the value of the expression automatically becomes a return value > No need to specify return > No need to enclose the expression with { } // Instead of this (myArg1, myArg2) → { return (someExpression); } // You can do this (myArg1, myArg2) → someExpression

28

Examples of Lambda Expression (int x, int y) -> { return x+y;} (x,y) -> { return x+y;} (x,y) -> x+y x -> x*2 () -> System.out.println(“Hello, world!”) x -> { System.out.println(x); System.out.println(x*2);}

29

Lab: Exercise 3: Lambda Expression Syntax Simplification 1621_java8_lambda_expression.zip

30

Method References

What is a Method Reference? • Method reference is just compact and more readable form of a lambda expression for already existing methods • The existing method should be assignable to a functional interface > The compiler knows the method signature (arguments) from the

functional interface

• “::” operator is used for method reference // Lambda expression MyFunctionalInterface myObject2 = () -> MyClass.existingStaticMethod(); myObject2.mySingleAbstractMethod(); // Method reference MyFunctionalInterface myObject3 = MyClass::existingStaticMethod; myObject3.mySingleAbstractMethod(); 32

4 Types of Method References • Reference to a static method - ClassName::staticMethod MyClass::myStaticMethod

• Reference to a constructor - ClassName::new String::new

• Reference to an instance method of a particular object objectOfClass::instanceMethod myObject::myInstanceMethod

• Reference to an instance method of an arbitrary object of a particular type - ContainingType::methodName String::compareToIgnoreCase 33

Reference to static method // Let's say you have defined a functional interface @FunctionalInterface interface MyFunctionalInterface { public void mySingleAbstractMethod(String name, int age); } // Let's also assume there is an existing static method in a class public class MyClass { public static void existingStaticMethod(String name, int age) { System.out.println(name + " is " + age + " years old."); } } // You would write a lambda expression as following MyFunctionalInterface myObject2 = (name, age) -> MyClass.existingStaticMethod(name, age); myObject2.mySingleAbstractMethod("Jon", 77); // The above lambda expression can be rewritten using a static method reference MyFunctionalInterface myObject3 = MyClass::existingStaticMethod; myObject3.mySingleAbstractMethod("Jon", 66);

34

Reference to Constructor - Class::new • Similar to static method reference - only difference is that the

method name is "new" (and, of course, the “new” constructor method already exists) // Let's say you have defined a functional interface @FunctionalInterface public interface MyFunctionalInterface { String createString(char[] cArray); } // You would write a lambda expression as following char[] charArray = { 'j', 'p', 'a', 's', 's', 'i', 'o', 'n' }; MyFunctionalInterface fi1 = cArray -> new String(cArray); System.out.println(fi1.createString(charArray)); // The above lambda expression can be rewritten using a constructor method reference MyFunctionalInterface fi2 = String::new; System.out.println(fi2.createString(charArray));

35

Reference to instance method of a particular object // Let's say you have defined a functional interface @FunctionalInterface interface MyFunctionalInterface { public void mySingleAbstractMethod(String name, int age); } // Let's also assume there is an existing instance method in a class public class MyClass { public void existingInstanceMethod(String name, int age) { System.out.println(name + " is " + age + " years old."); } } // You would write a lambda expression as following MyFunctionalInterface myObject2 = (name, age) -> MyClass.existingInstanceMethod(name, age); myObject2.mySingleAbstractMethod("Jon", 77); // The above lambda expression can be rewritten using an instance method reference MyFunctionalInterface myObject3 = MyClass::existingInstanceMethod; myObject3.mySingleAbstractMethod("Jon", 66);

36

Reference to instance method of an arbitrary object • When converting a method reference to a lambda, “if the desugared method is an instance method, the receiver is considered to be the first argument” • The lambda’s remaining arguments are passed as arguments to the referred method // You would write a lambda expression as following Arrays.sort(stringArray, (String a, String b) -> a.compareToIgnoreCase(b)); // The above lambda expression can be rewritten using an instance // method reference of an arbitrary object Arrays.sort(stringArray, String::compareToIgnoreCase);

37

Reference to instance method of a arbitrary object // Let's say you have defined a functional interface @FunctionalInterface interface MyInterface { R apply(T1 receiver, T2 argument1); } // Let's also assume there is an existing instance method in a class public class MyClass { Integer existingInstanceMethod(String s1) { System.out.println("length of " + s1 + " is " + s1.length()); return s1.length(); } } // lambda expression MyInterface myfunction1 = (MyClass myClass, String s1) -> myClass.existingInstanceMethod(s1); // method reference MyInterface myfunction2 = MyClass::existingInstanceMethod;

38

Lab: Exercise 4: Method References 1621_java8_lambda_expression.zip

39

Java 8 Provided Functional Interfaces

Functional Interfaces defined in Java 8 • Java 8 comes with newly defined functional interfaces in java.util.function package - so you don't have to define your own anymore > > > > > > > > >

Supplier Consumer Function Predicate UnaryOperator BiPredicate BiConsumer BiFunction BinaryOperator

() -> T T -> void T -> R T -> boolean T -> T (T,U) -> boolean (T,U) -> void (T,U) -> R (T,T) -> T

get() accept() apply() test() identity() test() accept() apply() apply() 41

Supplier

()->T

get()

• Represents a supplier of results > This is a functional interface whose functional method is get() > the type of results supplied by this supplier // Definition @FunctionalInterface public interface Supplier { T get(); } // Usage examples Supplier supplier1 = () -> "String1"; Supplier supplier2 = () -> "String1".length();

42

Consumer

T->void

accept()

• Represents an operation that accepts a single input argument and returns no result > This is a functional interface whose functional method is

accept(Object). > the type of the input to the operation // Definition @FunctionalInterface public interface Consumer { void accept(T t); }

// Usage Consumer function = x -> System.out.println(x); 43

Function

T->R

apply()

• Represents a function that accepts one argument and produces a result > The lambda expression is the body of the apply() method > the type of the input to the function > the type of the result of the function // Definition @FunctionalInterface public interface Function { R apply(T t); } // Usage examples Function function1 = x -> x.toUpperCase(); Function function2 = x -> x.length(); 44

Predicate T->boolean

test()

• Represents a predicate (boolean-valued function) of one argument. > the type of the input to the predicate // Definition @FunctionalInterface public interface Predicate { boolean test(T t); } // Usage examples Predicate function1 = x -> x > 10; Predicate function2 = s -> s.length() > 10;

45

UnaryOperator T->T

identity()

• java.util.function.UnaryOperator is a java 8 functional interface that extends java.util.function.Function • UnaryOperator is used to work on a single operand. It returns the same type as an operand // Definition @FunctionalInterface public interface UnaryOperator extends Function { static UnaryOperator identity() { return t -> t; } } // Usage Function function1 = x -> x.toUpperCase(); 46

Lab: Exercise 5: Java 8 Provided Functional Interfaces 1621_java8_lambda_expression.zip

47

Composition

Composition • Composition allows applying lambda expressions one after another • There are two methods: > Function compose(Function before) - The before function is

applied first and then the calling function > Function andThen(Function after) - The after function is applied after the calling function

49

andThen and compose // Functions without composition Function personToAddressFunction = Person::getAddress; Function addressToCountryFunction = Address::getCountry; Address address = personToAddressFunction.apply(new Person("Sang", new Address("Korea"))); String country = addressToCountryFunction.apply(address); // Functions with "andThen" composition Function personToCountryFunction1 = personToAddressFunction.andThen(addressToCountryFunction); country = personToCountryFunction1.apply(new Person("Jon",new Address("USA"))); // Functions with "compose" composition Function personToCountryFunction2 = addressToCountryFunction.compose(personToAddressFunction); country = personToCountryFunction2.apply(new Person("Jon",new Address("China"))); 50

Effectively Final Local Variables

Effectively Final Local variables • The local variables in the enclosing body can be accessible to Lambda expression • Lambda expression, however, cannot change them - they are behaving like final variables - effectively final local variables public class Main { public static void main(String[] args) {

}

int myInt = 100; Calculator multiply = (int x, int y) -> {return x * y * myInt;}; Calculator divide = (int x, int y) -> {myInt=30; return x * y * myInt;}; // compile error

} 52

Lab: Exercise 6: Effectively Final Local Variables 1621_java8_lambda_expression.zip

53

Code with Passion! JPassion.com

54

Java 8 Lambda Expression -

JavaScript, List, Scheme. > Ruby ..... The lambda expression is the body of the apply() method. > ... Composition allows applying lambda expressions one after.

1MB Sizes 7 Downloads 104 Views

Recommend Documents

Java 8 Lambda Expression -
JavaScript, List, Scheme. > Ruby ..... The lambda expression is the body of the apply() method. > ... Composition allows applying lambda expressions one after.

java 8.pdf
There was a problem previewing this document. Retrying... Download. Connect more apps... Try one of the apps below to open or edit this item. java 8.pdf.

G-lambda: Coordination of a Grid Scheduler and Lambda Path ...
Sep 27, 2006 - Network resource management techniques ... management system-based (management system interface has not been defined). ▫ OIF UNI 1.0/2.0 .... ▫Data management module: Stores reservation resource information.