Lambda Expressions in Java 8: Reading Material
Lambda Expressions in Java 8: Reading Material
Reading material:
Lambda Expressions in Java 8, by Cay Horstmann (Dr.
Dobbs): http://www.drdobbs.com/jvm/lambda-expressions-in-java-8/240166764
Java Tutorial:
https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
Lambda Quick Start:
http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/Lambda-QuickStart/index.html
Lambda Expressions in Java, by Angelika Langer & Klaus Kreft
http://www.angelikalanger.com/Lambdas/Lambdas.pdf
Overview
What is a λ-expression ?
Functional Interfaces
Motivation for Lambdas
Lambda Expression for Comparator
Lambda Expression Syntax
Closures and Variable Access
Dealing with Exceptions
Method References
Constructor References
Further Reading
What is a λ-expression ?
A block of code with parameters, i.e. a function with
no name that can access effectively final variables
from the surrounding scope (lexically scoped)
Captures free variables, instance and class
variables from the enclosing scope
Implemented with a closure.
Lambdas can be stored, referenced by variables
and passed around for execution at a later time
What is a λ-expression ?
It can be used anywhere where an object
implementing a functional interface is
expected
Other languages supporting lambdas:
JavaScript, C++, Python, Scala, LISP, Scheme,
Haskell, Matlab, F#, Perl, Lua, PHP, Ruby, TCL
Introduced by functional languages
Java is very late to this party
Functional Interfaces
A Java interface with only one abstract (i.e. unimplemented)
method declared in its definition
Optional Java annotation: @FunctionalInterface
Examples:
Collections.sort(countries,
new Comparator<Country>() parameter types
{
public int compare(Country country1, Country country2)
{
return country1.getName().compareTo(country2.getName());
}
} );
function definition
useful expression
Motivation for Lambdas
Sorting with anonymous class object: anonymous class
Collections.sort(countries,
new Comparator<Country>() parameter types
{
public int compare(Country country1, Country country2)
{
return country1.getName().compareTo(country2.getName());
}
});
function definition
useful expression
Collections.sort(countries,
(Country country1, Country country2) ->
country1.getName().compareTo(country2.getName());
);
If the compiler can infer parameter types, we can omit
them:
Collections.sort(countries,
(country1, country2) ->
country1.getName().compareTo(country2.getName());
);
Lambda Expression Syntax
For a code block of one statement:
(paramlist) -> expression
For a code block of multiple statements:
(paramlist) -> {
statement1; …....
statementn;
}
If the lambda returns a statement: use return expr;
(in this one line function example the { and } are optional.
I wrote them because of the comment.)
Closures and Variable Access
A closure is a function together with its environment:
– actual parameters, instance and class variables from
the enclosing class
– ... plus local variables that are effectively final (called
free variables)
new Thread(
( ) -> {
System.out.println(“thread started, index “ + index + “ at
time “ + now);
}
);
} // for i=...
Closures and Variable Access
Lexical scope: the lambda expression is not a scope
of it own, but it is part of the enclosing scope
“this” and “super” refer to the enclosing class
new Thread(
( ) -> {
System.out.println(“thread started by “ + this.toString()
+ “ object, with loop index “ + index);
}
);
} // for i=...
What are Lambdas, Actually ??
A lambda is represented in the JVM by an instance of an
anonymous and hidden class generated by the compiler, that
implements the target functional interface.
Lazy instantiation: object is not created unless used at runtime.
Example:
Comparator <String> comp = (s1, s2) -> {
if (s1.length() < s2.length()) return -1;
if (s1.length() > s2.length()) return +1;
return 0;
};
Class Object's Methods
Methods (toString, hashCode, equals, clone...)
are inherited by all classes → they are NOT
abstract.
A functional interface may include them:
@FunctionalInterface
interface Function1 <R,T> {
String toString(); // inherited from Object
jButton.addActionListener(
event -> System.out.println(event)
);
same as:
jButton.addActionListener(
System.out::println
);
Instance method
object reference from class PrintStream
Method References
Class::staticMethod
Suppose we want to create a stream of Doubles, compute square
roots for them, then display them to System.out:
dl.stream().map( Math::sqrt )
.forEach( y -> System.out.println(y) );
Method References
Class::instanceMethod
Suppose the functional interface abstract function is defined
as:
Type1 instanceMethod(Type2 y, Type3 z);
The first parameter in the lambda call becomes the target of
the method (the implicit parameter), the second becomes y,
the third becomes z, etc.
E.g. instance method compareTo() from class Double is defined
as:
int compareTo(Double other)
Method References
Class::instanceMethod (continued)
Sorting List <Double>:
Collections.sort(dl, Double::compareTo );
Constructor Reference
Similar to method references where the method name
is “new”.
Example: create array of JButtons from a list of labels
Function stream() creates a stream of objects
function map() calls the passed lambda on each stream
element and returns the new stream)
List<String> labels = new ArrayList<String>();
labels.add(“Hello”); labels.add(“Goodbye”);
The Java Stream API
https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html
Tutorials:
http://www.oracle.com/technetwork/articles/java/ma14-java-se-8-streams-2177646.html
http://winterbe.com/posts/2014/07/31/java8-stream-tutorial-examples/