Why do we need Lambda in Java?

why lambda

A lambda expression is a block of code that can be passed around to execute. It is a common feature for some programming languages, such as Lisp, Python, Scala, etc. But before Java 8, we can not do the same in Java. If we want a block of code to be executed, we need to create an object and pass the object around, such as using the strategy design pattern. From Java 8, lambda expressions enable us to treat functionality as method argument and pass a block of code around. Lambda expressions in Java 8 are very powerful and therefore very compelling. In this post, I will use a simple example to introduce functional programming in Java 8. This is a part of the series of Java 8 lambdas.

1. Sorting Before Java 8

The following example shows how to use a comparator to sort an array of self-defined objects.

This is the dog class that need to be sorted.

public class Dog {
	String name;
	int height;
	int weight;
 
	public Dog(String n, int s, int w) {
		this.name = n;
		this.height = s;
		this.weight = w;
	}
 
	public String toString() {
		return getName() + ": size=" + getHeight() + " weight=" + getWeight()
				+ " \n";
	}
 
	//setters and getters ... 
}

To sort an array of dogs, we can use Arrays.sort(...). The second parameter is a comparator. So we need to defined a comparator. This is a typical example of strategy pattern.

import java.util.Arrays;
import java.util.Comparator;
import java.util.stream.Stream;
 
public class ArraysSort {
 
	public static void main(String[] args) {
		Dog d1 = new Dog("Max", 2, 50);
		Dog d2 = new Dog("Rocky", 1, 30);
		Dog d3 = new Dog("Bear", 3, 40);
 
		Dog[] dogArray = { d1, d2, d3 };
		printDogs(dogArray);
 
		Arrays.sort(dogArray, new Comparator<Dog>() {
			@Override
			public int compare(Dog o1, Dog o2) {
				return o1.getWeight() - o2.getWeight();
			}
		});
		printDogs(dogArray);
	}
 
	public static void printDogs(Dog[] dogs) {
		System.out.println("--Dog List--");
		for (Dog d : dogs)
			System.out.print(d);
		System.out.println();
	}
}

2. Sorting with Java 8 Lambdas Expression

In Java 8, we can do sorting in one simple line of code like this:

Arrays.sort(dogArray, (Dog m, Dog n) -> m.getWeight() - n.getWeight());
printDogs(dogArray);

(Dog m, Dog n) -> Integer.compare(m.getWeight(), n.getWeight()) is a lambda expression. It is converted to an object of Comparator behind the scene. For now let’s simply consider the lambda expression as a function. How lambda expressions are converted to objects of functional interfaces is a more complicated story.

3. Syntax of Lambda Expression

The syntax of a lambda expression consists of the following:

  1. A comma-separated list of formal parameters enclosed in parentheses. In this case, it is (Dog m, Dog n)
  2. The arrow token ->
  3. A body, which consists of a single expression or a statement block. In this case, it is one single expression – Integer.compare(m.getWeight(), n.getWeight())

We can also write the lambda expression in other different ways.

4. Stream API

When we motivate why functional programming is so powerful in Java 8, the Stream API should be emphasized. A stream in Java 8 is a sequence of elements supporting sequential and parallel aggregate operations. By using streams, we can simply pass a block of code to the stream and apply the function to each element in the stream.

To sort the dog array above, we can also utilize the Stream API:

import java.util.stream.Stream;
 
public class Java8WhyLambda {
	public static void main(String[] args) {
		// create an array of dogs
		Dog d1 = new Dog("Max", 2, 50);
		Dog d2 = new Dog("Rocky", 1, 30);
		Dog d3 = new Dog("Bear", 3, 40);
		Dog[] dogArray = { d1, d2, d3 };
 
		// use stream to sort
		Stream<Dog> dogStream = Stream.of(dogArray);
		Stream<Dog> sortedDogStream = dogStream.sorted((Dog m, Dog n) -> Integer.compare(m.getHeight(), n.getHeight()));
 
		sortedDogStream.forEach(d -> System.out.print(d));
	}
}

4 thoughts on “Why do we need Lambda in Java?”

Leave a Comment