In this article, we will discuss difference between Anonymous Inner class and Lambda expression
First, we will look at what is anonymous inner classes in Java
1. Anonymous Inner class
- It is very simple to understand, a class which has no name at all
- In Java, every class has name which can be used to inherit further and can be used to create objects & invoke its method/behaviors using instantiated objects
- But in anonymous inner class, it is defined without name and used where it is defined i.e.; it scope limits to where is defined
- So further usage like inheriting and creating objects isn’t possible
- Note: Although it looks like similar to Lambda expression but their comparison is incomparable, we will look these points at the very end of this topic
- We will look at few examples of Anonymous inner class before comparing them with Lambda Expression (code-wise)
Example 1.A: Defining custom sorting logic using Comparator interface
- Below example shows that Comparator interface is instantiated to provide custom logic to sort list of String values
- It is used where it is defined i.e.; inside method itself
- Its further usage is not allowed, as it will act as local variable inside method it is defined
package net.bench.resources.custom.sorting.logic;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class MyCustomComparator {
public static void main(String[] args) {
// Step 1: define anonymous inner class for Comparator<String>
Comparator<String> cmp = new Comparator<String>() {
@Override
public int compare(String str1, String str2) {
return str1.compareTo(str2);
}
};
// Step 2: define ArrayList and add String values
ArrayList<String> al = new ArrayList<String>();
al.add("Poland");
al.add("Finland");
al.add("Denmark");
al.add("Sweden");
al.add("Norway");
System.out.println("Before Sorting - " + al);
// Step 3: sort ArrayList using above anonymous inner class Comparator
Collections.sort(al, cmp);
System.out.println("After Sorting - " + al);
}
}
Output:
Before Sorting - [Poland, Finland, Denmark, Sweden, Norway]
After Sorting - [Denmark, Finland, Norway, Poland, Sweden]
Example 1.B: Creating Thread using using Runnable interface
- Below example shows that Runnable interface is instantiated to provide logic for new thread inside run() method
package net.bench.resources.threads;
public class MyRunnable {
public static void main(String[] args) {
// Step 1: define anonymous inner class for Runnable
Runnable r = new Runnable() {
@Override
public void run() {
System.out.println("Hello World in Child Thread");
}
};
// Step 2: define Thread passing above Runnable instance
Thread t = new Thread(r);
// Step 2.A start runnable thread
t.start();
// main thread
System.out.println("Hello World in main Thread");
}
}
Output:
Hello World in main Thread
Hello World in Child Thread
2. Lambda Expression
- It is a new feature introduced in Java 1.8 version
- Which has special syntax like ( argument_list ) -> { function_body };
- Using Lambda Expression, code looks more concise which means less number of lines of code comparing with Anonymous Inner class
- Let us look at the same example discussed above using lambda expression
Example 2.A: Defining custom sorting logic using Comparator interface
- Above 1.A anonymous inner class example requires 5-6 lines of custom logic using Comparator interface for sorting
- The same example is reduced to single line using lambda expression
package net.bench.resources.custom.sorting.logic;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class MyComparator {
public static void main(String[] args) {
// Step 1: define Lambda Expression for Comparator<String>
Comparator<String> cmp = (str1, str2) -> str1.compareTo(str2);
// Step 2: define ArrayList and add String values
ArrayList<String> al = new ArrayList<String>();
al.add("Poland");
al.add("Finland");
al.add("Denmark");
al.add("Sweden");
al.add("Norway");
System.out.println("Before Sorting - " + al);
// Step 3: sort ArrayList using above anonymous inner class Comparator
Collections.sort(al, cmp);
System.out.println("After Sorting - " + al);
}
}
Output:
Before Sorting - [Poland, Finland, Denmark, Sweden, Norway]
After Sorting - [Denmark, Finland, Norway, Poland, Sweden]
Example 2.B: Creating Thread using using Runnable interface
- Above 2.A anonymous inner class example requires 5-6 lines of code for creating/spawning new thread from main thead
- Whereas same example is reduced to single line using lambda expression
package net.bench.resources.threads;
public class MyRunnableUsingLambda {
public static void main(String[] args) {
// Step 1: define Lambda Expression for Runnable
Runnable r = () -> System.out.println("Hello World in Child Thread");
// Step 2: define Thread passing above Runnable instance
Thread t = new Thread(r);
// Step 2.A start runnable thread
t.start();
// main thread
System.out.println("Hello World in main Thread");
}
}
Output:
Hello World in main Thread
Hello World in Child Thread
3. Anonymous Inner class v/s Lambda Expression
3.1 Anonymous Inner class :
- It can extend either concrete class or abstract class
- It can implement interface also
- An interface that anonymous inner class implements can contain any number of abstract methods
3.2 Lambda Expression :
- Lambda Expression can implement or provide implementation for Functional Interface only
- Functional Interface contains exactly one abstract method
- In addition to this, it can contains any number of default or static methods, which is another new feature introduced in Java 1.8 version
References:
- https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
- https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/Lambda-QuickStart/index.html
- https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html
- https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html
Happy Coding !!
Happy Learning !!