Archive
Java 8 : Functional Interface Example
To Support lambda expressions in Java 8, they introduced Functional Interfaces.
An interface which has Single Abstract Method can be called as Functional Interface.
Runnable, Comparator,Cloneable are some of the examples for Functional Interface. We can implement these Functional Interfaces by using Lambda expression.
For example:
Thread t =new Thread(new Runnable(){ public void run(){ System.out.println("Runnable implemented by using Lambda Expression"); } });
This is the old way of creating a Thread.
As Runnable is having Single Abstract Method, we can consider this as a Functional Interface and we can use Lambda expression like below.
Thread t = new Thread(()->{ System.out.println("Runnable implemented by using Lambda Expression"); });
Here instead of passing Runnable object we just passed lambda expression.
Declaring our own Functional Interfaces:
We can declare our own Functional Interface by defining Single Abstract Method in interface.
public interface FunctionalInterfaceTest{ void display(); } //Test class to implement above interface public class FunctionInterfaceTestImpl { public static void main(String[] args){ //Old way using anonymous inner class FunctionalInterfaceTest fit = new FunctionalInterfaceTest(){ public void display(){ System.out.println("Display from old way"); }}; fit.display();//outputs: Display from old way //Using lambda expression FunctionalInterfaceTest newWay = () -> {System.out.println("Display from new Lambda Expression");} newWay.display();//outputs : Display from new Lambda Expression } }
We can annotate with @FunctionalInterface annotation, to tell compile time errors. It is optional
for ex:
@FunctionalInterface public interface FunctionalInterfaceTest{ void display(); void anotherDisplay();//shows an error, FunctionalInterface should have only one abstarct method. }
Default Method:
Functional interface can not have more than one abstract method but it can have more than one default methods.
Default methods are introduced in Java 8, to add new methods to interface with out disturbing the implemented classes.
interface DefaultInterfaceTest{ void show(); default void display(){ System.out.println("Default method from interface can have body..!"); } } public class DefaultInterfaceTestImpl implements DefaultInterfaceTest{ public void show(){ System.out.println("show method"); } //we dont need to provide any implementation to default method. public static void main(String[] args){ DefaultInterfaceTest obj = new DefaultInterfaceTestImpl(); obj.show();//out puts: show method obj.display();//outputs : Default method from interface can have body..! } }
Main use of default method is with out forcing the implemented class , we can add a method to an interface.
Multiple Inheritance:
If the same default method is there in two interfaces and one class is implementing that interface, then it will throw an error.
//Normal interface with show method interface Test{ default void show(){ System.out.println("show from Test"); } } //Another interface with same show method interface AnotherTest{ default void show(){ System.out.println("show from Test"); } } //Main class to implement above two interfaces class Main implements Test, AnotherTest{ //here is an ambiguity which show method has to inherit here }
This class wont compile because there is an ambiguity between Test, AnotherTest interfaces show() method, to resolve this we need to override show() method to Main Class.
class Main implements Test, AnotherTest{ void show(){ System.out.println("Main show method"); } }
Java 8 : Lambda Example
Lambda Expressions:
Lambda expressions are new and important feature of Java 8. They provide a clear way to represent one method interface using lambda expression. And they provide easy way to access Collection libraries for iterating, filter and extract data.
Example :
Syntax : (arg1, arg2) -> {body}
For Ex:
(int a, int b) -> { return a + b; } () -> System.out.println("Hello World"); (String s) -> { System.out.println(s); } //Old way of iterating Collection List list = Arrays.asList(1, 2, 3, 4, 5, 6, 7); for(Integer n: list) { System.out.println(n); } //New way with lambda: List list = Arrays.asList(1, 2, 3, 4, 5, 6, 7); list.forEach(n -> System.out.println(n));
Rules:
- It can have zero or more number of arguments.
- Parameters are separated by using comma
- Empty parenthesis are used to represent empty parameters eg : () -> System.out.println(“Hello World”);
- Curly braces for body is not mandatory if it contains only single statement, other wise it should enclosed with curly braces.
Program:
interface TestInterface{ void display(); } public class TestInterfaceImpl{ public static void main(String[] args){ TestInterface li = new TestInterface(){ public void display(){ System.out.println("Hello World"); } }; li.display(); } }
Here we used anonymous class to implement TestInterface and this interface has only one method, by using lambda expression without using anonymous class we can call the display() method
interface TestInterface{ void display(); } public class TestInterfaceImpl{ public static void main(String[] args){ //Old way: TestInterface old = new TestInterface(){ public void display(){ System.out.println("Old : Display method called!"); } }; old.display(); //New way with Lambda expression TestInterface li = () -> System.out.println("New : Display method called !"); li.display(); } }
This approach we regularly use in Java Swing, while adding an action to Swing Component we use ActionListener actionPerformed() method, ActionListener is an interface which has only one method called actionPerformed(),
//old way: button.addActionListener(new ActionListener()){ public void actionPerformed(ActionEvent e){ System.out.println("The button was clicked using old fashion code!"); } } //New way: button.addActionListener( (e) -> { System.out.println("The button was clicked. From lambda expressions !"); });
java.util.Runnable also has only one method public void run(), this also we can represent using lambda
//old way Runnable r = new Runnable(){ public void run(){ System.out.println("Runnable run method"); } } //New way with lambda expression Runnable r = ()->System.out.println("Runnable run method"); //So we can create Thread object like below Thread t = new Thread(()->{System.out.println("Runnable run method from lambda")});
Any interface which has only one method can be used with lambda expression instead of old anonymous inner class.
Thanks for reading.