Skip to content

Lambdas ​

In order to pass a lambda function as an argument, it needs to be passed to a place that expects an interface that is a functional interface, or it only has one abstract method. This way the compiler can be sure that the function passed is the correct one for that interface.

The lambda function can also use variables in the calling scope, as long as the variables are final or effectively final.

java
@FunctionalInterface
public interface Operation<T> {
    T operate(T a, T b);
}

public static <T> T calculator(Operation<T> function, T v1, T v2) {
    T result = function.operate(v1, v2);
    return result;
}

public static void main() {
    List<Person> people = new ArrayList<>();
    people.sort((o1, o2) -> o1.lastName.compareTo(o2.lastName));

    int result = calculator((a,b) -> a + b, 5, 2);
}

Common Functional Interfaces ​

These are found in the java.util.function package. There are four basic types of functional interfaces.

  • Consumer -> void accept(T t, U u?) - Executes code without returning data (BiConsumer takes 2 args)
  • Function -> R apply(T t, U u?) - Return a result of an operation or function
  • Predicate -> boolean test(T t, U u?) - Test if a condition is true or false
  • Supplier -> T get() - Return an instance of something

Consumer ​

A Consumer interface takes one or two arguments and performs some operation on them without returning anything.

java
public static <T> void processPoint(T t1, T t2, BiConsumer<T,T> consumer) {
    consumer.accept(t1, t2);
}

public static void main() {
    BiConsumer<Double, Double> p1 = (lat, lng) -> System.out.printf("[lat:%.3f, long:%.3f]%n", lat, lng)
    processPoint(30.245, 50.343, p1);
}

Predicate ​

java
public static void main() {
    List<String> names = new ArrayList<>(List.of("Harry", "Ron", "Hermoine"))
    names.removeIf(s -> s.startsWith("H"));
}

Function ​

Similar to the Operation interface example above, this interface takes a lambda function and two values, performing some operation on the two with the apply method.

Operator ​

Operators have the same return and argument types, so only one type T. There are both UnaryOperators and BiOperators.

java
public static <T> T calculator(BinaryOperator<T> function, T v1, T v2) {
    T result = function.apply(v1, v2);
    return result;
}

Function ​

Functions can have different types for the return values and all of its arguments. There are both Functions and BiFunctions.

Method References ​

Method references allow you to pass a static method instead of a lambda function, and java can infer how to pass the arguments and what the return value should be. You pass a method reference by using the class name, two colons, and then the function name.

java
public static <T> T calculator(BinaryOperator<T> function, T v1, T v2) {
    T result = function.apply(v1, v2);
    return result;
}

public static void main() {
    calculator(Integer::sum, 2, 5);
    calculator(Double::sum, 7.5, 2.5);
}