Home > Tutorials > Java

How to use Java 8 Lambda Expressions

Last updated : December 9, 2020

Lambda expressions are a new feature added in Java 8. Lambda expressions can simplify the traditional way of using Collections and the way of handling concurrency.

Lambda expression is a block of code that takes parameters, processes, and returns a value. It is similar to a function without a name. Lambda expressions can be embedded in the body of a method similar to a statement. It simplifies coding by introducing expression to represent a single method interface.

Functional Interface

To make use of lambda expressions, you have to use functional interfaces. You can either create your own functional interface or use pre-defined functional interfaces provided by Java.

Functional interfaces have only one method defined in their interface definition. Other examples of such interfaces are java.lang.Runnable, java.awt.event.ActionListener, java.util.Comparator, and java.util.concurrent.Callable. Functional interfaces are also called Single Abstract Method interfaces (SAM)

Let's take a look at a simple interface implementation to perform arithmetic operations on two arguments.

interface Abacus {
    int operation(int a, int b);

Now let's take a look at lambda expressions that implement the above functional interface. When the method is called, the matching implementation will return the result of the mathematical operation.

public static void main(String args[]){
	Abacus add = (int a, int b) -> a + b;
	Abacus subtract = (a, b) -> a - b;
	Abacus multiply = (int a, int b) -> { return a * b; };
	Abacus divide = (int a, int b) -> a / b;

	System.out.println(add.operation(1, 5));
	System.out.println(subtract.operation(1, 5));
	System.out.println(multiply.operation(1, 5));
	System.out.println(divide.operation(1, 5));

The output would be the intended mathematical operation of two numbers. Although we implemented a simple calculation for demonstration purposes, real-world applications can contain fairly complex logic in place.

The output of the above code would look like:


In addition to the single method declared in the interface, we can also declare the abstract methods inherited from the java.lang.Object class in the functional interface. The interface can be annotated with @FunctionalInterface for validation purposes. In the below, we implement toString() and equals() methods inherited from Object.

interface Abacus {
    int operation(int a, int b);
    public String toString();
    public boolean equals(Object obj);

How to add custom methods to a functional interface?

If you want to add custom methods to the functional interface, you can use the default keyword to add any number of methods that are not abstract.

interface Abacus {
    int operation(int a, int b);
    public String toString();
    public boolean equals(Object obj);
    default int anotherAction(int a, int b){
    	return (a + b)*(a - b);

Sorting an array list with lambda

Let's take this array list and sort it both ways, traditional pre lambda code, and lambda code.

List letters = Arrays.asList("C", "B", "A", "E", "D");

Sorting without Lambda

Sorting an array list without lambda would involve an anonymous inner class. We use the inherited Object classes' compare method to compare each element in the array.

Collections.sort(letters, new Comparator() {
	public int compare(Object o1, Object o2) {
		return o1.toString().compareTo(o2.toString());

Sorting with Lambda

We can utilize ArrayList's sort method in combination with lambda expressions to sort our list.

letters.sort((o1,o2) -> o1.toString().compareTo(o2.toString()));

Or Collection's sort method

Collections.sort(letters,(o1,o2) -> o1.toString().compareTo(o2.toString()));

Note that we have eliminated the anonymous inner class and the number of code lines is also reduced.

By: Lance
Lance is a software engineer with over 15 years of experience in full-stack software development.

Leave a comment

No Comments