appendix b: lambda expressions in the technical keynote address for javaone 2013, mark reinhold,...

25
Appendix B: Lambda Expressions In the technical keynote address for JavaOne 2013, Mark Reinhold, chief architect for the Java Platform Group at Oracle, described lambda expressions as the single largest upgrade to the Java programming model ever. ©SoftMoore Consulting Slide 1

Upload: erik-townsend

Post on 25-Dec-2015

212 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Appendix B: Lambda Expressions In the technical keynote address for JavaOne 2013, Mark Reinhold, chief architect for the Java Platform Group at Oracle,

©SoftMoore Consulting

Appendix B: Lambda Expressions

In the technical keynote address for JavaOne 2013, Mark Reinhold, chief architect for the Java Platform Group at Oracle, described lambda expressions as the single largest upgrade to the Java programming model ever.

Slide 1

Page 2: Appendix B: Lambda Expressions In the technical keynote address for JavaOne 2013, Mark Reinhold, chief architect for the Java Platform Group at Oracle,

Java 8 Summary

• Lambda expressions, functional interfaces, and streams

• New date/time API

• Interfaces − can now contain static and default methods

• Nashorn JavaScript Engine (replaces Rhino)

• Other API additions/enhancements– JavaFX (Swing now in maintenance mode)– Concurrency– Collections– I/O– Security– …

©SoftMoore Consulting Slide 2

Page 3: Appendix B: Lambda Expressions In the technical keynote address for JavaOne 2013, Mark Reinhold, chief architect for the Java Platform Group at Oracle,

Lambda Expressions

• The major new features being added to Java 8 center around a functional programming construct known as a lambda expression.

• Lambda expressions simplify the implementation of certain types of programming problems.

• For example, many applications in mathematics require that a function (technically a pointer or reference to a function) be passed as a parameter.– easy to do in most other programming languages– cumbersome in Java prior to version 8

©SoftMoore Consulting Slide 3

Page 4: Appendix B: Lambda Expressions In the technical keynote address for JavaOne 2013, Mark Reinhold, chief architect for the Java Platform Group at Oracle,

A Motivating Example from Mathematics

• Simpson’s Rule is a numerical technique to approximate a definite integral; e.g., (Answer = 2; good test case.)

• Simpson’s Rule is an algorithm that computes an integral based on four parameters as follows:– A function that we want to integrate.– Two real numbers a and b that represent the endpoints of an

interval [a,b] on the real number line. (Note that the function should be continuous on this interval.)

– An even integer n that specifies a number of subintervals. In implementing Simpson's Rule we divide the interval [a,b] into n subintervals.

©SoftMoore Consulting Slide 4

0)sin( dxx

Page 5: Appendix B: Lambda Expressions In the technical keynote address for JavaOne 2013, Mark Reinhold, chief architect for the Java Platform Group at Oracle,

Simpson’s Rule in C++

C++ header file for Simpson's Rule (simpson.h)

#if !defined(SIMPSON_H)#define SIMPSON_H

#include <stdexcept>

using namespace std;

typedef double DoubleFunction(double x);

double integrate(DoubleFunction f, double a, double b, int n) throw(invalid_argument);

#endif

©SoftMoore Consulting Slide 5

Page 6: Appendix B: Lambda Expressions In the technical keynote address for JavaOne 2013, Mark Reinhold, chief architect for the Java Platform Group at Oracle,

©SoftMoore Consulting

Calling integrate() in C++

• Suppose that you want to test your implementation of Simpson’s Rule by approximating the integral of the sine function from 0 to π (PI) using 30 subintervals.

• Calling integrate is straightforward in C++.double result = integrate(sin, 0, M_PI, 30);

Slide 6

In C++ you pass the sine function as easilyas you pass the other three parameters.

Page 7: Appendix B: Lambda Expressions In the technical keynote address for JavaOne 2013, Mark Reinhold, chief architect for the Java Platform Group at Oracle,

Simpson’s Rule in Java

• Java interface for the function parameterpublic interface DoubleFunction { public double f(double x); }

• Java signature for method integrate in class Simpsonpublic static double integrate (DoubleFunction f, double a, double b, int n)

• The above is independent of whether or not we will use lambda expressions. The primary difference with lambda expressions is in how we pass parameters (more specifically, how we pass the function parameter) in a call to method integrate.

©SoftMoore Consulting Slide 7

Page 8: Appendix B: Lambda Expressions In the technical keynote address for JavaOne 2013, Mark Reinhold, chief architect for the Java Platform Group at Oracle,

©SoftMoore Consulting

Java Without Lambda Expressions(Version 1: Adapter Class)

• Create an adapter class that implements the DoubleFunction interface and wraps the call to Math.sin().import com.softmoore.math.DoubleFunction;

public class DoubleFunctionSineAdapter implements DoubleFunction

{ public double f(double x) { return Math.sin(x); } }

• Use the adapter class to call method integrate()DoubleFunctionSineAdapter sine = new

DoubleFunctionSineAdapter();double result = Simpson.integrate(sine, 0, Math.PI, 30);

Slide 8

Page 9: Appendix B: Lambda Expressions In the technical keynote address for JavaOne 2013, Mark Reinhold, chief architect for the Java Platform Group at Oracle,

Comments on Version 1

Compare the call to integrate() in C++ versus what was required to call integrate() in earlier versions of Java.

• With C++, we simply called integrate() passing in the four parameters.

• With Java, we had to create a new adapter class and then instantiate this class in order to make the call. If we wanted to integrate several functions, we would need to write adapter classes for each of them.

©SoftMoore Consulting Slide 9

Page 10: Appendix B: Lambda Expressions In the technical keynote address for JavaOne 2013, Mark Reinhold, chief architect for the Java Platform Group at Oracle,

Java Without Lambda Expressions(Version 2: Anonymous Class)

DoubleFunction sineAdapter = new DoubleFunction() { public double f(double x) { return Math.sin(x); } };

double result = Simpson.integrate(sineAdapter, 0, Math.PI, 30);

©SoftMoore Consulting Slide 10

Not much better.

Page 11: Appendix B: Lambda Expressions In the technical keynote address for JavaOne 2013, Mark Reinhold, chief architect for the Java Platform Group at Oracle,

Lambda Expressions

• A lambda expression is an annomous method; i.e., a block of code with parameters.

• Lambda expressions– are also known as closures, function literals, or simply lambdas– are formally defined by Java Specification Request (JSR) 335

• Motivation: to simplify the ability to create and use objects that are essentially functions.– provide better support for functional programming– provide a light-weight alternative to adapter classes and

anonymous classes for functional interfaces

©SoftMoore Consulting Slide 11

Page 12: Appendix B: Lambda Expressions In the technical keynote address for JavaOne 2013, Mark Reinhold, chief architect for the Java Platform Group at Oracle,

Functional Interfaces andLambda Expressions

• A functional interface is an interface with a single abstract method.– an interface that requires implementation of only a single method

in order to satisfy its requirements– Note: As of Java 8, interfaces can contain static and default

methods.

• Conversion to a functional interface is the only thing you can do with a lambda expression in Java.

©SoftMoore Consulting Slide 12

Note that DoubleFunction is a functional interface.

Page 13: Appendix B: Lambda Expressions In the technical keynote address for JavaOne 2013, Mark Reinhold, chief architect for the Java Platform Group at Oracle,

©SoftMoore Consulting

Examples of Functional Interfaces in Java

public interface Comparator<T> { int compare(T o1, T o2);

... // other default and static methods added in Java 8 }

public interface ActionListener extends EventListener { public void actionPerformed(ActionEvent e); }

public interface Runnable { public void run(); }

Slide 13

Page 14: Appendix B: Lambda Expressions In the technical keynote address for JavaOne 2013, Mark Reinhold, chief architect for the Java Platform Group at Oracle,

Annotating Functional Interfaces

• Java 8 has a new annotation, @FunctionalInterface, that can be used for functional interfaces.

• The annotation is not required, but if used,– it provides an extra check that everything is consistent

(similar to the @Override annotation in earlier versions of Java)– the javadoc page for the interface includes a statement that the

interface is a functional interface.

©SoftMoore Consulting Slide 14

Page 15: Appendix B: Lambda Expressions In the technical keynote address for JavaOne 2013, Mark Reinhold, chief architect for the Java Platform Group at Oracle,

Syntax of Lambda Expressions

Three parts

• A list of parameters enclosed in parentheses– Parameter types can be explicitly declared, or they can be

inferred from the context.– Empty parentheses indicate that there are no parameters.– For a single parameter whose type is inferred, parentheses may

be omitted

• An arrow token (->)

• A function body, which can be either of the following:– a statement block (enclosed in braces)– a single expression (return type is that of the expression)

©SoftMoore Consulting Slide 15

Page 16: Appendix B: Lambda Expressions In the technical keynote address for JavaOne 2013, Mark Reinhold, chief architect for the Java Platform Group at Oracle,

Examples of Lambda Expressions

(int x, int y) -> x + y// returns the sum of two integers

(x, y) -> x + y// returns the sum of two numbers (types are inferred)

n -> n % 2 == 0// returns true if n is even (type is inferred)

() -> 42 // constant function, no parameters// returns the answer to the ultimate question of// life, the universe, and everything

©SoftMoore Consulting Slide 16

Page 17: Appendix B: Lambda Expressions In the technical keynote address for JavaOne 2013, Mark Reinhold, chief architect for the Java Platform Group at Oracle,

Using a Lambda Expression(Version 1)

DoubleFunction sine = (double x) -> Math.sin(x);double result = Simpson.integrate(sine, 0, Math.PI, 30);

©SoftMoore Consulting Slide 17

Note that we did not have to write the adapter classor create an instance of an anonymous class.

Page 18: Appendix B: Lambda Expressions In the technical keynote address for JavaOne 2013, Mark Reinhold, chief architect for the Java Platform Group at Oracle,

©SoftMoore Consulting

Using a Lambda Expression(Version 2)

• The name of the functional interface is not part of the lambda expression but can be inferred based on the context.

• The type double for the parameter of the lambda expression can also be inferred from the context.

• If there is only one parameter in the lambda expression, the parentheses can be omitted.

• We can substitute the lambda expression inline as partof the call.

double result = Simpson.integrate(x -> Math.sin(x), 0, Math.PI, 30);

Slide 18

Page 19: Appendix B: Lambda Expressions In the technical keynote address for JavaOne 2013, Mark Reinhold, chief architect for the Java Platform Group at Oracle,

©SoftMoore Consulting

Using a Lambda Expression(Version 3)

• Another related feature in Java 8 is something called a method reference, which allows us to refer to an existing method by name.

• Method references can be used in place of lambda expressions as long as they satisfy the requirements of the functional interface.

• For static methods the syntax is Classname::methodName.

double result = Simpson.integrate(Math::sin, 0, Math.PI, 30);

Slide 19

Compare with C++ version.

Page 20: Appendix B: Lambda Expressions In the technical keynote address for JavaOne 2013, Mark Reinhold, chief architect for the Java Platform Group at Oracle,

The March of Progress(Cay Horstmann)

• 1980: C printf("%10.2f", x);

• 1988: C++ cout << setw(10) << setprecision(2) << showpoint << x;

• 1996: Java NumberFormat formatter = NumberFormat.getNumberInstance();

formatter.setMinimumFractionDigits(2); formatter.setMaximumFractionDigits(2); String s = formatter.format(x); for (int i = s.length(); i < 10; i++) System.out.print(' ');

System.out.print(s);

• 2004: Java System.out.printf("%10.2f", x);

©SoftMoore Consulting Slide 20

Page 21: Appendix B: Lambda Expressions In the technical keynote address for JavaOne 2013, Mark Reinhold, chief architect for the Java Platform Group at Oracle,

Another Example

• Suppose that you have an array of strings that you want to sort in two different ways– by their natural (lexicographic or alphabetic) ordering– by their length (shortest strings before longest)

String[] words = ... ;

• Consider two sorting methods in class Arraysstatic void sort(Object[] a)// sorts according to the natural ordering of its elements

static <T> void sort(T[] a, Comparator<? super T> c)// sorts according to the specified comparator

©SoftMoore Consulting Slide 21

Page 22: Appendix B: Lambda Expressions In the technical keynote address for JavaOne 2013, Mark Reinhold, chief architect for the Java Platform Group at Oracle,

©SoftMoore Consulting

Another Example(continued)

• CallingArrays.sort(words);

will sort the array according to the natural ordering of type String.

• To sort the array by the length of the strings, we can use a lambda expression.Arrays.sort(words, (word1, word2) -> Integer.compare(word1.length(), word2.length()));

Slide 22

Question: What about this for the Lambda expression?(word1, word2) -> word1.length() - word2.length()

O.k. for string lengths but not for comparing two integers ingeneral − can overflow for large operands with opposite signs.

Page 23: Appendix B: Lambda Expressions In the technical keynote address for JavaOne 2013, Mark Reinhold, chief architect for the Java Platform Group at Oracle,

Iterators in Java

• Version 1 (Enumerations in very early versions of Java)Enumeration e = names.elements();while (e.hasMoreElements()) { String name = (String) e.nextElement(); System.out.println(name); }

• Version 2 (Iterators since Java version 1.2)Iterator i = names.iterator();while (i.hasNext()) { String name = (String) i.next(); System.out.println(name); }

©SoftMoore Consulting Slide 23

Page 24: Appendix B: Lambda Expressions In the technical keynote address for JavaOne 2013, Mark Reinhold, chief architect for the Java Platform Group at Oracle,

Iterators in Java(continued)

• Version 3 (Enhanced for statement since Java 5)for (String name : names) System.out.println(name);

• Version 4 (New forEach() iterator in Java 8)names.forEach(name -> System.out.println(name));

©SoftMoore Consulting Slide 24

Note change from external (a.k.a. active) iteratorsto internal (a.k.a. passive) iterators.

See also the new Stream API for collections.− transformations (e.g., sorted, distinct, …)− filters (subcollection based on predicate)− reduction (max, count, …)− parallel versions

Page 25: Appendix B: Lambda Expressions In the technical keynote address for JavaOne 2013, Mark Reinhold, chief architect for the Java Platform Group at Oracle,

©SoftMoore Consulting

References

• Java 8 Centralhttp://www.oracle.com/technetwork/java/javase/overview/java8-2100321.html

• Java SE 8 for the Really Impatient, Cay Horstmann, Addison Wesley, 2014.http://www.informit.com/store/java-se-8-for-the-really-impatient-9780321927767

• Java Tutorial (new section on lambda expressions)http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html

• “Java programming with lambda expressions,” John I. Moore, Jr. JavaWorldhttp://www.javaworld.com/article/2092260/java-se/

java-programming-with-lambda-expressions.html

• State of the Lambda (Brian Goetz)http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-final.html

Slide 25