Lambda Expressions is an addition to Java which has caught everyone's attention. It is an interesting addition which will make code look cleaner and a bit smaller. To sum it up in one sentence - Lambda Expressions are a short-cut for implementing function interfaces.
What is a function interface?
A functional interface is an interface which has only one abstract method. Some common examples are Runnable
, ActionListener
etc.
How we used them earlier?
- By implementing it to a Class.
class FunctionalInterface1 implements Runnable { @Override public void run() { System.out.println("Hello from Thread!"); } public void startThread() { Thread thread=new Thread(this); thread.start(); } public static void main(String[] args) { new FunctionalInterface1().startThread(); } }
- By using Anonymous Classes.
class FunctionalInterface2 { public void startThread() { Thread thread=new Thread(new Runnable() { @Override public void run() { System.out.println("Hello from Anonymous Class!"); } }); thread.start(); } public static void main(String[] args) { new FunctionalInterface2().startThread(); } }
How to use Lamda Expressions?
Lambda Expressions have now made life easier by reducing by reducing it to a single line process. Here we go:
class LambdaTest {
public static void main(String args[]) {
Runnable r = () -> System.out.println("Hello from Lambda!");
r.run();
}
}
Just that much? Yes. Because a functional interfaces just has one abstract function, the ()
in the above code refers to the same function, run()
in the case of Runnable
.
The syntax of a Lambda Expression is
(args) -> Statement(s);
So, now you don't need to write tedious Anonymous classes for button ActionListener
. You can simply write
JButton button=new JButton("Lambda");
button.addActionListener((e) -> System.out.println("Action Performed!"));
or to sort arrays in alphabetical order for instance
String[] array = {"abc","fatir","abdul","hello"};
java.util.Arrays.sort(array, (s1,s2) -> s1.compareTo(s2));
Yes, you don't need to even mention the type of e (ActionEvent)
in the expression, JDK 8 understands it all.
In the following example I give examples of custom functional interfaces
interface OneOperandFunction {
public double compute(double a);
}
interface TwoOperandFunction {
public double compute(double a, double b);
}
public class CustomLambdas {
public static void main(String args[]) {
double x = 0.9, y = 56.8;
// No need to use return if you use no braces.
OneOperandFunction cube = a -> a*a*a;
// Use braces for multi-line Lambdas with a return statement
TwoOperandFunction expression = (a,b) -> {
double c = a*a;
double d = b-10;
return c*d;
};
System.out.println(cube.compute(x));
System.out.println(expression.compute(x,y));
}
}
The above code has two functional interfaces OneOperandFunction
and TwoOperandFunction
. The first one performs operations on one operand and the second one does the same on two operands.
You however won't create any new functional interfaces because JDK8 has made a lot of templates for you in the java.util.function
package. A few of them are
- Consumer<T> - Represents an operation that accepts a single input argument and returns no result.
- Function<T,R> - Represents a function that accepts one argument and produces a result.
- Predicate<T> - Represents a predicate (boolean-valued function) of one argument.4) Supplier<T> - Represents a supplier of results.
- UnaryOperator<T> - Represents an operation on a single operand that produces a result of the same type as its operand. 6) BinaryOperator<T> - Represents an operation upon two operands of the same type, producing a result of the same type as the operands.
- and many more.