Java Lambda expressions: what are they and how to use them?

Many Java developers have already encountered lambda expressions. This functionality was added in the 2014 version of Java 8, so it is no longer a new feature. It is often used by developers and has many advantages. However, if you find lambda expressions difficult or don’t know what they represent, you’ve come to the right place.

What is a lambda expression?

The lambda expression represents functionality that was added in Java 8. It is a short block of code similar to a method, but unlike it, it does not need the method’s name and can be implemented directly in the body of the method.

Lambda has several advantages, for example:

  • clarifies the code and provides better readability – instead of several lines of code, you only need to write a few lines,
  • allows to use functional programming – it means to use a function as an input parameter of another function,
  • improves code parallelization-in other words, more efficient code execution on multicore processes.

Syntax of lambda expression

Each lambda expression must have the correct syntax. Only in this case will it have the desired effect. Lambda must contain:

  • list of arguments,
  • the arrow sign,
  • the body of the expression.

In practice, it may look like this:

(argument list) -> expression body

(argument list) -> {expression1; expression2, …}

The argument list can also be empty, for example:

() -> { System.out.println(„Ahoj“); }

The body of the expression must contain compound parentheses only if it contains more than one line of code. In the above example, we can omit it:

() -> System.out.println(„Ahoj“);

The argument types may or may not be defined, which means that the two expressions are equivalent:

(x) -> System.out.println(x);

(Int x) -> System.out.println(x);

Lambda can also return values without using the return word. The compiler can derive it itself:

(x, y) -> x + y

Examples of lambda use

To give you a better idea, here are three examples of how a lambda expression can be used.

Example No. 1: Lambda expression in forEach

Lambda expressions are often used as a function parameter.

package com.test;

import java.util.ArrayList;

public class LambdaExample1 {

	public static void main(String[] args) {
		ArrayList<Integer> numbers = new ArrayList<Integer>();
		numbers.add(1);
		numbers.add(2);
		numbers.add(3);
		// Vytlaci na konzolu 1 2 3 pod sebou. 
		numbers.forEach(x -> System.out.println(x));
	}
}

The lambda expression can be saved in a variable. However, it only applies here if the variable interfaces with a single method. In such cases, the lambda expression must have the same number of parameters and return type as the method.

Java has many user interfaces. One example is the Consumer interface, which is used with lists:

java.util.function.Consumer<Integer> function = x -> System.out.println(x);
numbers.forEach(function);

Example No. 2: Defining a functional interface for a lambda expression

The second example shows the creation of a functional interface for basic mathematical operations. You can insert expressions for addition, subtraction, multiplication, division and the operate method. Its job is to take two numbers and the associated lambda expression calculates the result, which looks like this:

4 + 2 = 6 
4 - 2 = 2
4 * 2 = 8
4 / 2 = 2

Thanks to the operate method, the associated lambda expression calculates the result quickly and easily.

You can insert lambda expressions into the functional interface for basic mathematical operations.

package com.test;

import java.lang. ArithmeticException;

public class LambdaExample2 {
    // Deklarovanie interfejsu pre lamda vyraz
    interface MathOperation {
        int operation(int x, int y);
    }
    // Deklarovanie metody pre matematicku operaciu
    private int operate (int x, int y, MathOperation mathOperation) {
        return mathOperation.operation (x, y);
    }
    // Vypis celej operacie do konzoly.
    public static void printResult(int x, char c, int y, int z) {
        System.out.printf("%d %s %d = %d\n", x, c, y, z);
    }
    public static void main(String[] args) {
        // Bez deklaracie typu
        MathOperation addition = (x, y) -> x + y;
        // S deklaraciou typu (int)
        MathOperation substraction = (int x, int y) -> x - y;
        // S klucovym slovom return (musi byt v krutenych zatvorkach)
        MathOperation multiplication = (x, y) -> { return (x * y); };
        // Viacriadkovy lambda vyraz
        MathOperation division = (x, y) -> {
            if(y != 0)
                return (x / y);
            else
                throw new ArithmeticException("You shouldn't divide a number by zero!");
        };

        LambdaExample2 test = new LambdaExample2();
        int a = 4; int b = 2;
        // Scitanie dvoch cisiel
        printResult(a, '+', b, test.operate (a, b, addition));
        // Odcitanie dvoch cisiel
        printResult(a, '-', b, test.operate (a, b, substraction));
        // Vynasobenie dvoch cisiel
        printResult(a, '*', b, test.operate (a, b, multiplication));
        // Vydelenie dvoch cisiel
        printResult(a, '/', b, test.operate (a, b, division));
    }
}

Example No. 3: Sorting, filtering and iterating collections via lambda expressions

The advantage of lambda expressions is that they reduce the need to write custom helper methods. At the same time, they also shorten and clarify the code, making the whole job easier. The power of lambdas stands out especially when combined with other Java functionality, such as collections.

In the following example we will show how to easily sort, filter and iterate objects in a collection using lambda expressions:

package com.test;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

class Product {
    String name;
    double price;

    public Product(String name, double price) {
        this.name = name;
        this.price = price;
    }
}

public class LambdaExample3 {

    public static Product createProduct(String name, double price) {
        return new Product(name, price);
    }

    public static void main(String[] args) {
        List<Product> products = new ArrayList();
        products.add(createProduct("Chlieb", 1.0));
        products.add(createProduct("Mlieko", 0.5));
        products.add(createProduct("Keksy", 0.8));
        products.add(createProduct("Smotana", 0.4));
        products.add(createProduct ("Cokolada", 0.7));

        // Sortovanie nazvov produktov podla abecedy cez lambdu
        products.sort((p1, p2) -> p1.name.compareTo(p2.name));

        // Vyfiltrovanie produktov s cenou (0.5. 1.0)
        Stream<Product> filteredProducts = products.stream().filter(p -> p.price > 0.5 && p.price < 1.0);

        // Iterovanie v kolekcii
        filteredProducts.forEach(product -> System.out.println(product.name + ": " + product.price));
    }
}

The output you will get looks like this:

Cokolada: 0.7
Keksy: 0.8

Lambda expressions make work easier and faster

Lambda expressions are a great functionality in the Java programming language. Using them can make the whole job easier and faster. In addition, they clarify the code and open up new possibilities. Lambda has been part of Java since Java 8. So if you’re running an older version, it’s worth thinking about upgrading.

We have prepared files with the mentioned Java Lambda examples for you, which you can run directly in Java. Download the code here.

About the author

Jozef Wagner

Java Developer Senior

Viac ako 10 rokov programujem v Jave, momentálne pracujem v msg life Slovakia ako Java programátor senior a pomáham zákazníkom implementovať ich požiadavky do poistného softvéru Life Factory. Vo voľnom čase si rád oddýchnem v lese, prípadne si zahrám nejakú dobrú počítačovú hru.

Let us know about you