Java Lambda Expressions: Functions as First-Class Citizens

Since Java 8, a lot of boilerplate code can be replaced with lambda expressions in our codebase. I really want to put out an article about Streams in Java, but since that carries real value only if we combine them with lambda expressions, I want to write about some ideas about playing around with lambda expressions first.

Functional Interfaces in Java

A functional interface is an interface with a single abstract method, also known as SAM (Single Abstract Method) types. The concept was introduced in JDK 8, but there were interfaces prior to JDK 8 that complied with that definition. For example, Comparator has only one method:compare().

We can create our own as:

interface Calculator<T,R> {
    R calculate(T a, T b);


Here, the @FunctionalInterface annotation is checked by the compiler. So, if the interface does not contain exactly one abstract method, there is a compiler error.

It is not necessary to use this annotation when providing a type for a lambda expression, but, like other annotations (@Override, for example), it is a best practice to use it because it tells the compiler to check that it would work — otherwise, it will be overlooked until runtime.

Now, What Is a Lambda Expression?

A lambda expression is an inline implementation of a functional interface, eliminating the need of an anonymous class.

A lambda expression has three parts:

parameters [zero or more]
code block [if more than one statement, enclosed in curly braces { . . . } ] 
           [may contain free variables; values for these supplied by local or instance vbles]


For example:

(a,b) -> a + b; // given two numbers a and b, return another number with their summation.

(String str) -> System.out.println(str); // prints the given string into console

The equivalent of the first lambda expression is:

new Calculator<Integer, Integer>() {    
    public Integer calculate(Integer a, Integer b) {        
        return a + b;    


You can see how lambda expressions help to get rid of the boilerplate code.

Naming Lambda Expressions

Every object in Java has a type; the same is true of lambda expressions. The type of a lambda expression is any functional interface for which the lambda expression is an implementation.

Naming a lambda expression is done by using an appropriate functional interface as its type, like naming any other object. For example:

Calculator<Integer, Integer> adder = (a,b) -> a + b;

The name of this lambda expression is adder of type Calculator.

Note: I am omitting the parameter type because if parameter types can be inferred, they can be omitted. So, the above expression with the parameter type would be:

Calculator<Integer, Integer> adder = (Integer a,Integer b) -> a + b;


Using Lambda Expressions

You've seen how inner class approximations can be replaced by lambda expressions, which capture their essential functional nature: Arguments mapped to outputs. Hence, the functions are now first-class citizens. So:

1. A lambda expression can be used as a regular class object to call the method. For example, adder can be used to call the calculate method as:

Integer sum = adder.calculate(3,4); // sum = 7


2. Lambda expressions can be passed as an argument and used to evaluate expressions as:

// ...
// ...

static void printSum(Calculator cal) {


3. Lambda expressions can be returned as a return object:

// ...
Calculator<Integer, Integer> multiplier = getCalculatorFunc();
Integer result = multiplier.calculate(6,9));  // 54
// ...
static Calculator getCalculatorFunc() {
    Calculator<Integer, Integer> multiplier = (a, b) -> a * b;
    return multiplier;



Now, you can see how it is possible to reap many of the benefits of Functional Programming while maintaining the OO essence of the Java language as a whole. Lambda expressions are the fundamentals for functional programming and writing code concisely with Streams, which I want to continue in the next post. Until then, happy coding!

The source code for the examples presented above is available on GitHub.