Channels ▼
RSS

JVM Languages

Lambda Expressions in Java 8


Java was designed in the 1990s as an object-oriented programming language, when object-oriented programming was the principal paradigm for software development. Long before there was object-oriented programming, there were functional programming languages such as Lisp and Scheme, but their benefits were not much appreciated outside academic circles. Recently, functional programming has risen in importance because it is well suited for concurrent and event-driven (or "reactive") programming. That doesn't mean that object orientation is bad. Instead, the winning strategy is to blend object-oriented and functional programming. This makes sense even if you are not interested in concurrency. For example, collection libraries can be given powerful APIs if the language has a convenient syntax for functional expressions.

The principal enhancement in Java 8 is the addition of functional programming constructs to its object-oriented roots. In this article, I demonstrate the basic syntax and examine how to use it several important contexts. The key points are:

  • A lambda expression is a block of code with parameters.
  • Use a lambda expression whenever you want a block of code executed at a later point in time.
  • Lambda expressions can be converted to functional interfaces.
  • Lambda expressions can access effectively final variables from the enclosing scope.
  • Method and constructor references refer to methods or constructors without invoking them.
  • You can now add default and static methods to interfaces that provide concrete implementations.
  • You must resolve any conflicts between default methods from multiple interfaces.

Why Lambdas?

A lambda expression is a block of code that you can pass around so it can be executed later, just once or multiple times. Before getting into the syntax (or even the curious name), let's step back and see where you have used similar code blocks in Java all along.

When you want to do work in a separate thread, you put the work into the run method of a Runnable, like this:

class Worker implements Runnable {
     public void run() {
        for (int i = 0; i < 1000; i++)
           doWork();
     }
     ...
  }

Then, when you want to execute this code, you construct an instance of the Worker class. You can then submit the instance to a thread pool, or keep it simple and start a new thread:

Worker w = new Worker();
  new Thread(w).start();

The key point is that the run method contains code that you want to execute in a separate thread.

Consider sorting with a custom comparator. If you want to sort strings by length instead of the default dictionary order, you can pass a Comparator object to the sort method:

class LengthComparator implements Comparator<String> {
     public int compare(String first, String second) {
        return Integer.compare(first.length(), second.length());
     }
  }
  
Arrays.sort(strings, new LengthComparator());

The sort method keeps calling the compare method, rearranging the elements if they are out of order, until the array is sorted. You give the sort method a snippet of code needed to compare elements, and that code is integrated into the rest of the sorting logic, which you'd probably not care to reimplement. Note that the call Integer.compare(x, y) returns zero if x and y are equal, a negative number if x < y, and a positive number if  x > y. This static method was added to Java 7. You shouldn't compute x - y to compare x and y because that computation can overflow for large operands of opposite sign.

As another example for deferred execution, consider a button callback. You put the callback action into a method of a class implementing the listener interface, construct an instance, and register the instance with the button. That happens so often that many programmers use the "anonymous instance of anonymous class" syntax:

button.setOnAction(new EventHandler<ActionEvent>() {
     public void handle(ActionEvent event) {
        System.out.println("Thanks for clicking!");
     }
  });

What matters is the code inside the handle method. That code is executed whenever the button is clicked.

Since Java 8 positions JavaFX as the successor to the Swing GUI toolkit, I use JavaFX in these examples. (See Eric Bruno's posts for more information on JavaFX. — Ed.) The details don't matter. In every user interface toolkit, be it Swing, JavaFX, or Android, you give a button some code that you want to run when the button is clicked.

In all three examples, you saw the same approach. A block of code was passed to someone — a thread pool, a sort method, or a button. The code was called at some later time.

Up to now, giving someone a block of code hasn't been easy in Java. You couldn't just pass code blocks around. Java is an object-oriented language, so you had to construct an object belonging to a class that has a method with the desired code.

In other languages, it is possible to work with blocks of code directly. The Java designers have resisted adding this feature for a long time. After all, a great strength of Java is its simplicity and consistency. A language can become an unmaintainable mess if it includes every feature that yields marginally more-concise code. However, in those other languages, it isn't just easier to spawn a thread or to register a button-click handler; large swaths of their APIs are simpler, more consistent, and more powerful. In Java, one could have written similar APIs that take objects of classes implementing a particular function, but such APIs would be unpleasant to use.

For some time now, the question was not whether to augment Java for functional programming, but how to do it. It took several years of experimentation before a design emerged that is a good fit for Java. In the next section, you will see how you can work with blocks of code in Java 8.

The Syntax of Lambda Expressions

Consider the previous sorting example again. We pass code that checks whether one string is shorter than another. We compute

Integer.compare(first.length(), second.length())

What are first and second? They are both strings! Java is a strongly typed language, and we must specify that as well:

(String first, String second)
     -> Integer.compare(first.length(), second.length())

You have just seen your first lambda expression! Such an expression is simply a block of code, together with the specification of any variables that must be passed to the code.

Why the name? Many years ago, before there were any computers, the logician Alonzo Church wanted to formalize what it means for a mathematical function to be effectively computable. (Curiously, there are functions that are known to exist, but nobody knows how to compute their values.) He used the Greek letter lambda (λ) to mark parameters. Had he known about the Java API, he would have written:

λfirst.λsecond.Integer.compare(first.length(), second.length())

Why the letter λ? Did Church run out of other letters of the alphabet? Actually, the venerable Principia Mathematica used the ˆ accent to denote free variables, which inspired Church to use an uppercase lambda (Λ) for parameters. But in the end, he switched to the lowercase version. Ever since, an expression with parameter variables has been called a "lambda expression."


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Comments:

Video