A Quick Introduction to Java 8 Lambdas
Pinterest Stumbleupon Whatsapp
Advertisement

If you’re a Java programmer and you’re interested in learning more about Java 8 lambdas, in this article we’re going to take a closer look at lambda syntax and usage.

A lambda expression in Java is a concise way to express a method of a class in an expression. It has a list of parameters and a body. The body can be a single expression or a block 10 Core Java Concepts You Should Learn When Getting Started 10 Core Java Concepts You Should Learn When Getting Started Whether you are writing a GUI, developing server-side software, or a mobile application using Android, learning Java will serve you well. Here are some core Java concepts to help you get started. Read More . It is commonly used where an implementation of an interface is required. This need usually arises when an interface is required as the argument to invoke a method.

Some Simple Lambda Expressions

Let us look at some simple examples of lambda expressions.

The following is a lambda expression which accepts two numbers x and y and computes the sum.

(int x,int y) -> x + y;

Drop the parameter types for a more concise representation:

(x, y) -> x + y;

Define a function which accepts no parameters:

() -> 404;

The following is valid too, which accepts no parameters and returns nothing:

() -> {}

No need for parantheses enclosing parameters for a single parameter:

x -> x + 1

More complex code blocks are also possible. The following lambda accepts a single line parameter and does some processing on it. Note that the type of the parameter is inferred from the surrounding context:

line -> {
String[] x = pattern.split(line);
return new Player(Integer.parseInt(x[0]),
                  x[1],
                  x[2],
                  x[3],
                  Integer.parseInt(x[4]));
}

Clean and Concise Coding

Using lambda expressions helps make your code clean and concise. To assist in this, Java 8 classes make extensive use of lambdas.

Looping Over a List or a Set

Collection classes such as List, Set, Queue, and such implement the Iterable interface which makes looping over the elements much easier.

Declare a list of names.

List<String> names = Arrays.asList("Joe", "Jack", "James", "Albert");

Loop over the list without lambda:

for (String name : names) {
    System.out.println(name);
}

Using lambda, the above loop can be written as:

names.forEach(name -> System.out.println(name));

With Java 8 method references, the above can be written even more concisely as:

names.forEach(System.out::println);

Looping Over a Map

A Map is a mapping of keys to values. Looping over a map involves looping over each of the (key, value) mapping. Compare how you can use lambdas for this situtation.

First define a map:

Map<String,Integer> map = new HashMap<>();
map.put("Atlanta, Georgia", 110);
map.put("Austin, Texas", 115);
map.put("Baltimore, Maryland", 105);
map.put("Birmingham, Alabama", 99);
map.put("Boston, Massachusetts", 98);

You can loop over this map in the traditional way:

for (Map.Entry<String,Integer> e : map.entrySet()) {
    System.out.println(e.getKey() + " => " + e.getValue());
}

Here is how you can do the same thing in a quick and concise way using lambdas:

map.forEach((k, v) -> System.out.println(k + " => " + v));

Functional Interfaces

What is the return type of a lambda expression? In other words, what is the type of X in the following statement?

X x = a -> a + 1;

The return type of a lambda expression is a functional interface – an interface with a single abstract method. You can assign a lambda expression to an interface with a compatible abstract method. Some examples below.

Creating a Multi-Threaded Task

Consider creating a task for execution in a separate thread 4 Methods for Writing Multi-Threaded Code in Java 4 Methods for Writing Multi-Threaded Code in Java In this article, we compare a few of options for writing multi-threaded code in Java, so you can better judge which option to use for your next Java project. Read More — you are required to define the task as a Runnable interface and implement the run() method. Here Runnable is a functional interface.

class MyTask implements Runnable {
   ...
   public void run() {
     // implement your task here
     System.out.println("Running in a separate thread now.");
   }
   ...
}

You can then create an instance of the MyTask class and use it to start a new thread of execution.

MyTask task = new MyTask();
Thread thread = new Thread(task);
thread.start();

Using a lambda, the process of creating a Runnable becomes much easier. The task definition above can be rewritten as:

Runnable task = () -> System.out.println("Running in a separate thread now.");

Or even:

Thread thread = new Thread(() -> System.out.println("Running in a separate thread now."));
thread.start();

Comparison Using a Comparator

The Comparator is a functional interface for comparing objects of a given type. It defines a single abstract method called compare() which can be defined using a lambda expression.

Here is a lambda expression creating a Comparator used to compare strings case-insensitively.

Comparator<String> cmp = (x, y) -> x.compareToIgnoreCase(y);

Once an instance of the Comparator functional interface has been created, it can be re-used as required.

Here, we sort a list of strings in ascending order.

List<String> names = Arrays.asList("Joe", "Jack", "James", "Albert");
Collections.sort(names, cmp);
names.forEach(System.out::println);
// prints
Albert
Jack
James
Joe

The list above is sorted in place. We can now search it using the binarySearch() method as follows:

System.out.println("search(Joe):" + Collections.binarySearch(names, "Joe", cmp));
# prints
search(Joe):3

Computing maximum and minimum from a list is also easy using lambdas.

Define some data:

List<Integer> temps = Arrays.asList(110, 115, 105, 99, 98, 54, 109, 84, 81, 66, 72, 135, 115, 75, 82, 90, 88);

Use a lambda expression to define the comparator:

Comparator<Integer> cmpTemp = (x, y) -> Integer.compare(x, y);

And print the maximum and minimum:

System.out.println("------ Max/Min ------");
System.out.println(Collections.max(temps, cmpTemp) + "/" + Collections.min(temps, cmpTemp));

Use in GUI Programming

Lambda expressions are also extremely useful in GUI programming to implement event handlers. Here is an example of using a button click handler.

JButton button = new JButton("Click Me");
button.addActionListener(e -> System.out.println("Button clicked!"));

And that was a quick look at using lambdas in Java 8.

Have lambdas made your life easier since Java 8? Please explain in the comments below.

Enjoyed this article? Stay informed by joining our newsletter!

Enter your Email

Leave a Reply

Your email address will not be published. Required fields are marked *

  1. Doc
    November 25, 2017 at 6:58 pm

    "No need for parantheses..." **parentheses** Please, PLEASE proofread your articles! #MathFAIL