Java 8 Lambda's are nice but nothing exciting
Lambda - sounds pretty intimidating but they're actually pretty simple, and they do not do anything you can't already do. I like them because when used properly, they can make code that little bit clearer; readability is a good thing!
Are you seated? Lambda's are ... just anonymous methods, methods that aren't attached to a class, and that don't require any object instantiation for a to be passed around as arguments to other methods. They are a prettier way to write uber short methods (they don't have to be short, but it is considered a best practice).
There are very few simple rules as to what makes a Lambda (aka functional interface), and just a few best practices.
A Lambda is an interface with only 1 method. For example, the Runnable interface can be used as a Lambda as it only defines the single method run.
For clarity, it is considered best practice to annotate your functional interface with @FunctionalInterface.
It is best practice to avoid mutating any external variables so that the Lambda remain thread-safe.
Best practice to keep your implementation short and sweet.
Use the Java supplied functional interfaces over creating own if possible.
Keep them pure ie the same inputs should always return the same outputs. In this way they can be safely used in Java 8's Streams.
Lambda's using Java 8's 2 in-built functional interfaces
import java.util.function.BiFunction;
import java.util.function.Function;
public class LambdaExample {
// i'm just using n for name
static Function<String, String> greet = n -> "Hello " + n;
// i'm just using s for salutation and n for name
static BiFunction<String, String, String> bespokeGreet = (s, n) -> s + " " + n;
public static void main(String[] args) {
// built-in functional interface that takes a single input arg
System.out.println(greet.apply("Steve"));
// built-in functional interface that takes two input args
System.out.println(bespokeGreet.apply("Yo","Steve"));
}
}
Alternative to above wihout Lambda's
public class NonLambdaExample {
static String greet(String n) {
return "Hello " + n;
}
static String bespokeGreet(String s, String n) {
return s + " " + n;
}
public static void main(String[] args) {
// built-in functional interface that takes a single input arg
System.out.println(greet("Steve"));
// built-in functional interface that takes two input args
System.out.println(bespokeGreet("Yo","Steve"));
}
}
Not exactly a stark difference in the very simplistic examples above. The bigger difference is seen when passing Lambda's into other methods
Lambda as arg
import java.util.function.Function;
public class LambdaExample {
// i'm just using n for name
static Function<String, String> greet = n -> "Hello " + n;
static void printGreeting(String name, Function<String, String> greetMethod) {
System.out.println(greetMethod.apply(name));
}
public static void main(String[] args) {
// built-in functional interface that takes a single input arg
printGreeting("Steve", greet);
}
}
Vs non-lambda as arg
public class LambdaExample {
// i'm just using n for name
String greet(String n) {
return "Hello " + n;
}
static void printGreeting(String name, LambdaExample le) {
System.out.println(le.greet(name));
}
public static void main(String[] args) {
// built-in functional interface that takes a single input arg
printGreeting("Steve", new LambdaExample());
}
}
The main difference? In the non-lambda example we've had to instantiate a new Object for passing as the arg!