Cs Java2 12 Java8 en
Cs Java2 12 Java8 en
Simon Kroly
[email protected]
Interfaces
Static methods
for eliminating external utility classes (e.g. Collections).
E.g. list.sort(comparator) using a default method from the List interface and a static
method from the Comparator interface
Default methods
Extending existing interfaces: these methods are inherited by the implementations,
explicit implementations are not required. E.g. if an interface already has several
implementations, it can be extended without modifying the classes.
The mechanism can be used for extending APIs without losing backward compatibility
Interfaces
Sample interface:
public interface Presentable {
void doSomething();
default void doSomethingByDefault() {
System.out.println("Default implementation");
}
static void executeUtilityMethod() {
System.out.println("Static method");
}
}
Sample implementation:
public class Sample implements Presentable {
@Override
public void doSomething() {
System.out.println("Method implementation within the class");
}
}
Lambda expression
Anonymous function (in the Computer Science domain)
Observation: a more exact definition is used within the Mathematics domain (lambda calculus)
Other terms: lambda abstraction, lambda function, function literal, anonymous function
Sometimes closure is also used as a synonym (especially in the Java domain), but this is not completely
correct from a theoretical point of view
Usage:
Passing functions as parameters to other functions
Returning functions from other functions
Lambda expression vs. (?) closure
Closure: function/function reference + environment/context information (the set of variables within the
lexical scope of the function) non-local free variables can be accessed by the function, even if it is called
from outside its lexical scope (captured variables)
Lexical/static scoping: the variables declared within a function can be accessed by another function, also
declared within the same function (if the usage of embedded functions is allowed)
Before Java 8 we already had a limited support for closures, using inner classes
From a theoretical point of view: not all lambda expressions are closures (it is not sure that an anonymous
function has access to non-local variables) and not all closures are lambda expressions (not only
anonymous functions have access to non-local variables)
But: lambda expressions are frequently implemented using closures. This method is used by Java the
terms are often used as synonyms within the community (e.g. Closure was the name of the project
initiated for introducing lambda expressions in Java).
Lambda expressions
Syntax:
Parameter types can be explicitly declared, or implicitly discovered (no combination is
allowed within a single expression)
The parenthesis can be omitted if a single parameter is present
Within the last example the operations defined by the lambda expression were performed
on a collection, but any other type can be used, if the methods can be called for that
instance.
Usage a simple example:
public static void main(String[] args) {
Runnable r = () -> System.out.println("Hello Lambda!");
r.run();
}
Lambda expressions are objects. But: they dont have a unique identity.
They are instances of functional interfaces. These interfaces are subtypes of the Object
superclass. The methods of the Object superclass are inherited by these interfaces, but
the equals method can not be interpreted (because lambdas dont have an identity).
They can be used anywhere, if a target type is required in the current context:
Variable declarations, assignment operations
Return statements
Parameters for methods and constructors
Lambda expressions
Callable<Runnable> c = () -> () -> { System.out.println("hi"); };
Cast expressions:
Object o = (Runnable) () -> { System.out.println("hi"); };
Lambda scope
No new naming context is introduced by a lambda expression. Within a lambda expression the
variable names are interpreted in the same way as in the external environment. (Of course,
formal parameters are exceptions.)
The this and super keywords have the same interpretation within the lambda and its external environment
Class and instance variables are hidden by the formal parameters
class Sample { int i; Something s = i -> i * 2; };
Implementing a listener:
b.addActionListener(e -> System.out.println(e.getActionCommand() + " pressed."));
Constructor:
private static List<Person> copyCollection(List<Person> src, Supplier<List<Person>> dest) {
List<Person> result = dest.get();
for (Person p:src) {
result.add(p);
}
return result;
}