Java Lambda Expressions

A lambda expression (Java 8) is a short way to write an anonymous function. It is mostly used to pass a small piece of behavior to a method, for example how to sort or how to filter a list.

Syntax

(parameters) -> expression
(parameters) -> { statements; }

From the old way to a lambda

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<String> names = new ArrayList<>(List.of("Meera", "Al", "Riya", "Karan"));

        // old way: an anonymous class
        Collections.sort(names, new Comparator<String>() {
            @Override
            public int compare(String a, String b) {
                return a.length() - b.length();
            }
        });
        System.out.println(names);

        // lambda
        names.sort((a, b) -> b.length() - a.length());
        System.out.println(names);

        // method reference
        names.sort(String::compareTo);
        System.out.println(names);
    }
}
Output

[Al, Riya, Meera, Karan]
[Meera, Karan, Riya, Al]
[Al, Karan, Meera, Riya]

Functional interfaces

A lambda works with an interface which has one abstract method. The package java.util.function has the common ones:

InterfaceMethodMeaningExample
Predicate<T>boolean test(T)A yes or no questionn -> n > 5
Function<T,R>R apply(T)Change a value into anothers -> s.length()
Consumer<T>void accept(T)Do something with a values -> System.out.println(s)
Supplier<T>T get()Make a value() -> 42
UnaryOperator<T>T apply(T)Same type in and outs -> s.trim()
BinaryOperator<T>T apply(T, T)Two in, one out(a, b) -> a + b
import java.util.function.*;

public class Fn {
    public static void main(String[] args) {
        Predicate<Integer> isEven = n -> n % 2 == 0;
        Function<String, Integer> length = s -> s.length();
        Consumer<String> shout = s -> System.out.println(s.toUpperCase() + "!");
        Supplier<Double> pi = () -> Math.PI;
        BinaryOperator<Integer> add = (a, b) -> a + b;

        System.out.println(isEven.test(10));
        System.out.println(length.apply("lambda"));
        shout.accept("hello");
        System.out.println(pi.get());
        System.out.println(add.apply(4, 5));

        // combine
        Predicate<Integer> bigAndEven = isEven.and(n -> n > 100);
        System.out.println(bigAndEven.test(102));
        Function<Integer, Integer> twice = n -> n * 2;
        System.out.println(twice.andThen(n -> n + 1).apply(5));
    }
}
Output

true
6
HELLO!
3.141592653589793
9
true
11

Lambdas with collections

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

public class Coll {
    public static void main(String[] args) {
        List<Integer> numbers = new ArrayList<>(List.of(1, 2, 3, 4, 5, 6));

        numbers.removeIf(n -> n % 2 == 1);
        System.out.println(numbers);
        numbers.replaceAll(n -> n * n);
        System.out.println(numbers);
        numbers.forEach(n -> System.out.print(n + " "));
        System.out.println();

        Map<String, Integer> map = new TreeMap<>(Map.of("a", 1, "b", 2));
        map.forEach((k, v) -> System.out.println(k + "=" + v));
    }
}
Output

[2, 4, 6]
[4, 16, 36]
4 16 36
a=1
b=2

Method references

When the lambda only calls one method, you can write it shorter with ::.

KindExampleSame as
Static methodInteger::parseInts -> Integer.parseInt(s)
Instance method of a typeString::lengths -> s.length()
Method of an objectSystem.out::printlnx -> System.out.println(x)
ConstructorArrayList::new() -> new ArrayList<>()

Variables in lambdas

A lambda can use the local variables of the method, but they must be final or effectively final (not changed after they are set):

public class Eff {
    public static void main(String[] args) {
        int count = 0;
        Runnable r = () -> count++;       // error: count is changed
        r.run();
    }
}
Output

Eff.java:4: error: local variables referenced from a lambda expression must be final or effectively final
Runnable r = () -> count++; // error: count is changed
^
1 error
error: compilation failed

Note: Keep lambdas short. If you need more than 2 or 3 lines, write a normal method and use a method reference. Next: Java Streams.

Congratulations! Chapter Finished. Learn more about the similar topics:
Exercises & Assignments
No Content Found.
Interview Questions & Answers
No Content Found.