Lambda expressions

Setting the scene: anonymous classes!

Lambdas are anonymous functions. They were added to Java since Java 8 was released. Lambdas can be used in any place a Single Abstract Method was used before.

Let's showcase the use of Lambdas through a demo.

@SuppressWarnings("All")
public class LambdaDemo {
public static void main(String[] args) {
}
private static List<Author> getSampleAuthors() {
List<Author> authors = new ArrayList<>();
authors.add(new Author("Franz Kafka", 12, "Bohemian"));
authors.add(new Author("Sadegh Hedayat", 60, "Persian"));
authors.add(new Author("J. k. Rowling", 31, "British"));
return authors;
}
}

We start with using anonymous inline classes.

private static void usingAnonymousInlineClass() {
List<Author> authors = getSampleAuthors();
Collections.sort(authors, new Comparator<Author>() {
@Override
public int compare(Author a1, Author a2) {
return a1.getName().compareTo(a2.getName());
}
});
for (Author a: authors) {
System.out.println(a);
}
}

Call usingAnonymousInlineClass in main and it must print out the sample authors sorted by name.

Lambda expression

An interface that only has one unimplemented abstract method is called functional interface in Java. In the example we saw above, Comparator is a functional interface as it only has one unimplemented asbstract method named compare that any implementing class must implement. We can use lambda expressions since Java 8 to implement a functional interface. In other words, we can just directly provide an implementation for the abstract method wherever a functional interface is expected. Alright, let's do the same thing we did above this time with a lambda function!

private static void usingLambdaInLongForm() {
List<Author> authors = getSampleAuthors();
Collections.sort(authors, (Author a1, Author a2) -> {
return a1.getName().compareTo(a2.getName());
});
for (Author a: author) {
System.out.println(a);
}
}

The following is syntax sugar for anonymous inline implementation of Comparator.

(Author c1, Author a2) -> {
return a1.getName().compareTo(a2.getName());
}

You've used syntax sugar before: the enhanced for loop is syntax sugar for looping through the use of an iterator:

Iterator<Author> it = authors.iterator();
while (it.hasNext()) {
Author a = it.next();
System.out.println(a);
}

Bak to Lambdas, let's simplify our lambda expression:

private static void usingLambdaInShortForm() {
List<Author> authors = getSampleAuthors();
Collections.sort(authors, (a1, a2) -> a1.getName().compareTo(a2.getName()));
authors.forEach(author -> System.out.println(author));
}
tip
  • You don't need to specify the data type of arguments.
  • When the body of your lambda function is a single statement, you can eliminate the { } and the return keyword.

Also note the use of forEach method:

authors.forEach(author -> System.out.println(author));