Lambda expressions in Java

Aleksei Dudchenko
2 min readNov 18, 2022

--

Lambda expressions have been available since Java 8 and are perhaps the most prominent feature added in this release.

Why do we need them and what they are made for? I'll try to cover this in this article.

Oracle Java Documentation says:

One issue with anonymous classes is that if the implementation of your (1)anonymous class is very simple, such as an interface that contains only one method, then the syntax of anonymous classes may seem unwieldy and unclear. In these cases, you’re usually trying to (2)pass functionality as an argument to another method, such as what action should be taken when someone clicks a button. Lambda expressions enable you to do this, to (3)treat functionality as method argument, or code as data.

wow wow wow… Let’s go step by step.

(1)Anonymous class is like a local class, but it doesn't have a name. It can be used when you need to use the local class only once. The class can be declared and instantiated at the same time.

If your class has only one method, with lambdas you can declare the method directly without declaring and instantiating the class, even an anonymous class.

(2)Pass functionality as an argument to another method is about programming on an interface level, not the implementation one — one of OOP's good practices. Having a list of buttons all implementing an interface Clickable, we don’t need to write classes with method implementation and instantiate them. We don’t even need to write an anonymous class anymore. With lambda expressions, we can define the functionality of the methods right in the code.

hard-coded implementation:

btn.setOnAction(new MyButtonEventHandler<ActionEvent>());

public class MyButtonEventHandler<T> implements EventHandler<ActionEvent> {

@Override
public void handle(ActionEvent actionEvent) {
System.out.println("Hello World!")
}
}

anonymous class:

btn.setOnAction(new EventHandler<ActionEvent>() {

@Override
public void handle(ActionEvent event) {
System.out.println("Hello World!")
}
});

with lambda expression

btn.setOnAction(event -> System.out.println("Hello World!"));

What is important, the setOnAction() method has the following signature

public final void setOnAction(EventHandler<ActionEvent>)

and EventHandler is a Functional Interface which simply means it has only one method. You can annotate it with @FunctionalInterface just to make sure that no one can add another method without removing this annotation.

@FunctionalInterface
public interface EventHandler<T extends Event> extends EventListener {
void handle(T var1);
}

(3)Treat functionality as method argument, or code as data. You can refer to your lambda expressions in code, e.g. you can pass a lambda expression as an argument or as if it was an object.

    
EventHandler<ActionEvent> myButtonEventHandler = event -> System.out.println("Hello World!");

btn.setOnAction(myButtonEventHandler);

In this context think about how Decorator design pattern will change. There is a good example provided here https://www.javacodegeeks.com/2015/12/java-8-lambda-expression-design-patterns-decorator-design-pattern.html

--

--