How to use Java 8 Lambda Expressions

Last updated : Jul 30, 2023 12:00 AM

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.

Simple interfaceDescription
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.

Simple interface implementationDescription
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:

OutputDescription
6
-4
5
0

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.

Annotated interfaceDescription
@FunctionalInterface
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.

Add custom methodsDescription
@FunctionalInterface
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 to ArrayDescription
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() {
    @Override
    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.

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

Or Collection's sort method

List to ArrayDescription
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.

Lance

By: Lance

Hi, I'm Lance Raney, a dedicated Fullstack Developer based in Oklahoma with over 15 years of exp

Read more...