Lambdas in Java: what are they, and why are they useful?
Lambda expressions or lambdas are functions that can be used as though they were ordinary variables or expressions.
Using a lambda expression in Java, we can refer to a piece of code almost as easily as we can refer to an ordinary object or value. This allows us to:
- pass a piece of code as an argument to a method;
- return a piece of code as the result from a method;
- declare a variable that refers to a particular piece of code;
- invoke the piece of code referred to by a particular method, argument or variable.
There are a variety of cases where lambdas are useful. Example uses of lambdas include:
- Comparators: A routine to sort a list of items could take a comparison function as one of its parameters, allowing the same overall routine to be used for different orderings (sort by name, sort by size etc);
- Callbacks and event handlers: When calling a method that performs an asynchronous or "background" task, the caller can supply a piece of code to be executed on completion of the background task ("completion handler"); similarly, it might supply a piece of code to be executed if the task fails ("failure event handler");
- Lazy initializers: For so-called "lazy initialization", where we ask some object manager for an object to be created later in time when it is needed, we can tell the object manager what code to execute to initialize instances of the object as they are required.
- Getter fucntions: We could write a formatting routine to format and print the dates and capitalised descriptions of data items passed into it; given the date and description of a particular item, our method would know how to format the date and capitalise the description, but the code to retrieve the date and description from an item in question would be passed into our method.
- Visitors: For routines that traverse a tree of data (e.g. a file system directory tree) and perform a particular action on each item encountered, using a lambda expression allows us define the action to be executed on each item.
All of the above couold be done without lambdas, using existing Java language features such as interfaces or anonymous classes. Prior to the introduction of lambdas in Java 8, all of the above could be achieved, and indeed, were achieved in the relevant standard Java APIs. But having to create an anonymous class just to pass a piece of code from one method to another meant that functions or blocks of code were not "first-class citizens" of the language: you could not assign them to variables, pass them into methods or declare them in the first place as straightforwardly as a numeric type or object reference. From Java 8 onwards, lambdas provide a more efficient solution, both in terms of the code that needs to be written and in terms of the resulting implementation and performance. As we will see, many of the Java APIs have been updated to allow lambdas to be used as comparators, callbacks and the other typical uses that we have just described.
Getting started with lambdas
On the next page, we provide a more detailed introduction to lambdas in Java.
Subsequent pages will look at various associated topics including: