DEV Community

Cover image for Lambdas in Java
Cesar Castro
Cesar Castro

Posted on

Lambdas in Java

Lambdas in Java

Lambdas are undeclared functions, meaning they do not need to be explicitly declared to be used. There is no need to specify a name, parameters, access modifiers, or return type. Essentially, a lambda is a simpler way to implement an interface with a single method.

In Java, the basic syntax of lambda functions is:

(args) -> (body)
Enter fullscreen mode Exit fullscreen mode

Examples

(int x, int y) -> { return x * y; }
Aluno display = (Pessoa p) -> { System.out.println(p.idade); }
() -> System.out.println(new Date());
() -> { return 25.789; }
x -> x < 100;
Enter fullscreen mode Exit fullscreen mode

Curly braces are required only when the function body contains more than one statement. For example:

(int x, int y) -> { return x * y; }
Enter fullscreen mode Exit fullscreen mode

Can be written as:

(int x, int y) -> return x * y;
Enter fullscreen mode Exit fullscreen mode

Both forms produce the same result.

Lambda functions can have parameters or none at all. The parameter types can also be omitted, as Java will infer their types.

Examples

  1. Function with parameters (with declared types):
   (int x, int y) -> { return x * y; }
Enter fullscreen mode Exit fullscreen mode
  1. Function with parameters (without declared types):
   (x, y) -> { return x * y; }
Enter fullscreen mode Exit fullscreen mode
  1. Function without parameters:
   () -> System.out.println(new Date());
Enter fullscreen mode Exit fullscreen mode

If no return keyword is used, the function's return type is inferred as void:

(a) -> this.x = a;
Enter fullscreen mode Exit fullscreen mode

It is important to note that lambdas are different from anonymous classes. This can be observed in the generated .class files. Unlike anonymous classes, lambdas do not generate multiple .class files for each usage.


Applications of Lambdas in Java

Threads

Lambdas simplify code by reducing verbosity when working with threads.

// Implementing the Runnable interface and creating a thread with it
Runnable e = new Runnable() {
    public void run() {
        System.out.println(new Date());
    }
};
new Thread(e).start();

// The same implementation using a lambda expression
Runnable e = () -> System.out.println(new Date());
new Thread(e).start();

// Even more concise
new Thread(
    () -> System.out.println(new Date())
).start();
Enter fullscreen mode Exit fullscreen mode

Collections

Lambdas simplify functions such as sorting and filtering in collections.

// Print all elements in a list
List<String> list = Arrays.asList("João", "Ana", "Maria", "Cesar");
for (String s : list) {
    System.out.println(s);
}

// Using lambdas
list.forEach(s -> System.out.println(s));

// Lambda with multiple statements
list.forEach(s -> {
    if (StringUtils.equals("Cesar", s)) {
        System.out.println(s);
    }
});

// Conventional sorting
Collections.sort(list, new Comparator<String>() {
    @Override
    public int compare(String s1, String s2) {
        return s1.compareTo(s2);
    }
});
list.forEach(p -> System.out.println(p));

// Sorting using lambdas
Collections.sort(list, (String s1, String s2) -> s1.compareTo(s2));
list.forEach(p -> System.out.println(p));
Enter fullscreen mode Exit fullscreen mode

Listeners

Lambdas simplify code in listeners, which implement the Observer design pattern.

// Listening to an action on a button in a Swing window
button.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("Some actions...");
    }
});

// Using lambdas
button.addActionListener((e) -> {
    System.out.println("Some actions...");
});
Enter fullscreen mode Exit fullscreen mode

Generic Functions

Lambdas can be used in generic functions to solve problems by passing lambda expressions as parameters.

public class Main {
    /*
    * A method that tests a condition
    */
    public static void testExpression(List<String> list, Predicate<String> predicate) {
        list.forEach(n -> {
            if (predicate.test(n)) {
                System.out.println(n);
            }
        });
    }

    /*
    * Calling the method with a lambda
    */
    public static void main(String[] args) {
        List<String> list = Arrays.asList("João", "Ana", "Maria", "Cesar");
        // Prints "Cesar" if it exists
        testExpression(list, (n) -> StringUtils.equals("Cesar", n));
        // Prints the entire list
        testExpression(list, (n) -> true);
        // Prints nothing
        testExpression(list, (n) -> false);
    }
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)