Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations


Presentation on theme: "Appendix B: Lambda Expressions In the technical keynote address for JavaOne 2013, Mark Reinhold, chief architect for the Java Platform Group at Oracle,"— Presentation transcript:

1 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 ConsultingSlide 1

2 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 ConsultingSlide 2

3 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 ConsultingSlide 3

4 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 ConsultingSlide 4

5 Simpson’s Rule in C++ C++ header file for Simpson's Rule ( simpson.h ) #if !defined(SIMPSON_H) #define SIMPSON_H #include using namespace std; typedef double DoubleFunction(double x); double integrate(DoubleFunction f, double a, double b, int n) throw(invalid_argument); #endif ©SoftMoore ConsultingSlide 5

6 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); ©SoftMoore ConsultingSlide 6 In C++ you pass the sine function as easily as you pass the other three parameters.

7 Simpson’s Rule in Java Java interface for the function parameter public interface DoubleFunction { public double f(double x); } Java signature for method integrate in class Simpson public 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 ConsultingSlide 7

8 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); ©SoftMoore ConsultingSlide 8

9 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 ConsultingSlide 9

10 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 ConsultingSlide 10 Not much better.

11 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 ConsultingSlide 11

12 Functional Interfaces and Lambda 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 ConsultingSlide 12 Note that DoubleFunction is a functional interface.

13 Examples of Functional Interfaces in Java public interface Comparator { 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(); } ©SoftMoore ConsultingSlide 13

14 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 ConsultingSlide 14

15 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 ConsultingSlide 15

16 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 ConsultingSlide 16

17 Using a Lambda Expression (Version 1) DoubleFunction sine = (double x) -> Math.sin(x); double result = Simpson.integrate(sine, 0, Math.PI, 30); ©SoftMoore ConsultingSlide 17 Note that we did not have to write the adapter class or create an instance of an anonymous class.

18 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 part of the call. double result = Simpson.integrate(x -> Math.sin(x), 0, Math.PI, 30); ©SoftMoore ConsultingSlide 18

19 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); ©SoftMoore ConsultingSlide 19 Compare with C++ version.

20 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 ConsultingSlide 20

21 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 Arrays static void sort(Object[] a) // sorts according to the natural ordering of its elements static void sort(T[] a, Comparator c) // sorts according to the specified comparator ©SoftMoore ConsultingSlide 21

22 Another Example (continued) Calling Arrays.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())); ©SoftMoore ConsultingSlide 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 in general − can overflow for large operands with opposite signs.

23 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 ConsultingSlide 23

24 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 ConsultingSlide 24 Note change from external (a.k.a. active) iterators to 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

25 References Java 8 Central http://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. JavaWorld http://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 ©SoftMoore ConsultingSlide 25


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

Similar presentations


Ads by Google