Lambda Expressions For Beginners

Writing Your First Lambda Expression For Beginners In Java

Lambda Expressions are commonly used as a more compact alternative to anonymous classes.

Lambda Expressions can also come in handy when you intend to pass a particular behavior to different parts of your code. i.e


        Comparator<String> strCompByLength = (String x, String y) -> {
            return Integer.compare(x.length(), y.length());
        };

As you would notice, we're using a Lambda Expression to implement Comparator<T> functional interface.

Here, we're basically defining a comparator implementation that compares 2 String objects based on their length.

Let's have a more detailed example to enable you have a good grasp of Lambda expressions.

TIP: For those who would like to follow along with this article, just clone my repository git clone https://github.com/steven7mwesigwa/java-tutorials.git and navigate to java-tutorials/functional-programming-with-streams/first-lambda-expression-for-beginners/. In there, you should be able to play around with all the source code used here.

Let's create a simple POJO Student.java class that we'll play with for our example. Essentially, this can be data coming from a Repository or a file.


//Student.java
package com.stevenmwesigwa.first.lambda.expression;
			
public class Student {

    private String firstname;

    public Student(String firstname) {
        this.firstname = firstname;
    }

    public String getFirstname() {
        return firstname;
    }

}
Let's say we've been given a task to sort Students by their firstname. Meaning that the one with the shortest firstname will come first. Now truthfully speaking, there would be multiple implementations to accomplish this task.

But we'll use Arrays.sort(T[] a, Comparator<? super T> c) just to drive the point home.

Let's create a class AnonymousClassSyntax.java as our main class for the actual implementation.



//AnonymousClassSyntax.java
package com.stevenmwesigwa.first.lambda.expression;

import java.util.Arrays;
import java.util.Comparator;
			
public class AnonymousClassSyntax {

    public static void main(String[] args) {
        Comparator<Student> compByLength = new Comparator() {
            @Override
            public int compare(Student x, Student y) {
                return Integer.compare(x.getFirstname().length(), y.getFirstname().length());
            }
        };
        Student[] students = {new Student("Dimitri"), new Student("Sam"), new Student("Peter")};

        Arrays.sort(students, compByLength);

        for (Student student : students) {
            System.out.println(student.getFirstname());
        }
    }

}

Basically,we're defining a comparator implementation compByLength using anonymous class syntax. This compares Student objects by the length of their firstname.

As you can notice, we're basically providing our own implementation of the compare method required by the Comparator functional interface.

We're then providing Arrays.sort() method with our array of Student objects together with the comparator implementation.

We then finally print out a list of Students sorted in a way that the one with the shortest firstname length comes first. i.e



...	
Sam
Peter
Dimitri
...

Now let's improve this code by making use of Lamda Expressions.

# Using A Lambda Expression



		//RegularLambdaExp.java
		package com.stevenmwesigwa.first.lambda.expression;
		//...
		
		        Comparator<Student> compByLength = (Student x, Student y) -> {
            return Integer.compare(x.getFirstname().length(), y.getFirstname().length());
        };
		
		//...
		

With Lambda Expressions, we write less code. Additionally, we don't write a new keyword. We don't repeat stating the interface name.

We just write the parameter list (Student x, Student y), an arrow -> and the body {...} of the abstract method.

This is common when working with functional interfaces because functional interfaces usually have a single abstract method so there is no ambiguity as to which abstract method we're implementing. Here, all we have to implement is the compare method required by Comparator<T> functional interface.

#Lambda Expressions : Removing Parameter Types



		//NoParameterTypes.java
		package com.stevenmwesigwa.first.lambda.expression;
		//...
		
        Comparator<Student> compByLength = (x, y) -> {
            return Integer.compare(x.getFirstname().length(), y.getFirstname().length());
        };
		
		//...
		

As you would notice, we haven't defined any parameter types i.e (x, y) .

We didn't have to specify that these are Student objects. The compiler will be able to figure this out because we're assigning this lambda expression to a Comparator of Student.

#Lambda Expressions : Removing Curly Braces And Return Keyword



		//NoCurlyBracesAndReturnKeyword.java
		package com.stevenmwesigwa.first.lambda.expression;
		//...
		
        Comparator<Student> compByLength = (x, y) ->  Integer.compare(x.getFirstname().length(), y.getFirstname().length());
		
		//...
		

In cases where we have a single "one liner" statement and the statement is a return statement, we can get rid of both the curly braces { } and the return keyword.

NOTE: You can't keep the return keyword without wrapping the body with curly braces. You'll receive a compile time error when you do this.

#Lambda Expressions : Expression With No Parameters



		//NoParameters.java
		package com.stevenmwesigwa.first.lambda.expression;
		//...
		
         Runnable r = () -> {
            System.out.println("I am a Runnable {r}!!");
        };
        Thread t1 = new Thread(r);
				
				 t1.run();
		
		//...
		

Let's consider a situation where our expression doesn't take any parameters.

The Runnable functional interface is commonly used in multithreading to specify the behavior of Threads. This interface requires you to implement a run() method that takes no arguments.

As you may notice, Our Lamda expression now has an empty list of parameters and then the body.

We then pass this object to a constructor of a Thread.

#Bonus Tip!

We can combine these 2 lines into a single line by passing the lambda expression directly to the constructor of the Thread. i.e



		//NoParameters.java
		package com.stevenmwesigwa.first.lambda.expression;
		//...
		
        Thread t2 = new Thread(() -> {
            System.out.println("I am a Runnable {t2}!!");
        });
				
				 t2.run();
		
		//...
		

Notice here that we didn't even need to state the Runnable interface. Our compiler would basically figure out that the Thread constructor expects a Runnable object. Therefore, this lambda expression is implementing Runnable. Hence, the function body is the body of the run() method.

#Lambda Expressions : Accepting A Single Parameter



		//SingleParameter.java
		package com.stevenmwesigwa.first.lambda.expression;
		//...
		
         Consumer<String> consumer = e -> System.out.printf("%s : %d \n", e, e.length());

        String[] names = {"Steven", "Wesley", "Dimitri", "Denzel", "Mwesigwa"};
        for (String name : names) {
            consumer.accept(name);
        }
		
		//...
		

Above, We consider a situation where our lambda expression accepts a single parameter.

In this case, we can easily eliminate wrapping parentheses around your single parameter.

A Consumer<T> is simply another functional interface that has an abstract method called accept(T t). This method performs an operation on a given argument and returns no value.

In the example above, we're simply printing each name in an array with its "character count" to standard output.

As always, remember that all the source code used in this article can be found on my github page ready for you to play with.

It's been a pleasure taking you through lambda expressions.

If anything is unclear or you wish to make any corrections, don't hesitate to leave a comment. Your feedback is greatly appreciated.

Sharing is caring. Share this article to help out others getting started with Lambda Expressions.

Have a good day!

About The Author   

Steven Mwesigwa

Software Engineer at Vogue Book Consultancy Services Ltd


Picture Of Steven Mwesigwa

Steve is currently a software developer at Vogue Book Consultancy Services Ltd and a technology author. He holds a Dip. in civil engineering from Kyambogo University. He founded and maintains stevenmwesigwa.com a website that receives more than 1.5 thousand visits per month. Steve can be reached on Twitter at @steven7mwwesigwa