- It is a realization of a functional interface.
- It should not change the state of the modifying objects.
- Modifying instance variables inside a lambda expression is a bad practice, because of thread safety.
class Person{
String name;
Person(String name){
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
}
@FunctionalInterface
interface Func<T>{
T get();
}
public class Test {
public static void main(String[] args){
Person p = new Person("Sam");
Func<String> lambdaFun = () -> {
// [ DISCOURAGED ] modifying enclosing instance variable p
p.name = "dominic";
return p.name;
};
System.out.println(p); // Person{name='Sam'}
System.out.println(lambdaFun.get()); // dominic
System.out.println(p); // Person{name='dominic'}
}
}
- can only access final variables of the enclosing scope.
public class Test {
public static void main(String[] args){
int myVar = 42;
Supplier<Integer> lambdaFun = () -> myVar; // java: local variables referenced from a lambda expression must be final or effectively final
myVar++; // it makes myVar mutable
System.out.println(lambdaFun.get());
}
}
-
object::instanceMethod:
Given an object ob and an instance method meth() in ob, the lambda expression x -> ob.meth(x) can be written as ob::meth
E.x: button.setOnAction(evt -> p.print(evt)) as button.setOnAction(p::print)
-
Class::staticMethod:
Given a class ClassName and one of its static methods meth(), the lambda expression x -> ClassName.meth(x)
// or (x,y) -> ClassName.meth(x,y) if meth accepts two arguments can be rewritten as ClassName::meth
E.x: BiFunction<Integer, Integer, Double> f = (x,y) -> Math.pow(x, y) as BiFunction<Integer, Integer, Double> f = Math::pow
-
Class::instanceMethod:
Given a class ClassName and one of its instance methods meth(), the lambda expression (x,y) -> x.meth(y) can be rewritten as
ClassName::meth.
E.x: (str1, str2) -> str1.compareToIgnoreCase(str2) as String::compareToIgnoreCase
-
Class::new:
Ex: new String() as String:new