Benefits of lambda expressions in Java make the move to a newer JDK worthwhile
Java lambda expression benefits
If you haven’t used lambda expressions before, you might be wondering what the fuss is all about. After all, at the most basic level, a lambda expression is nothing more than a new, somewhat simpler way to implement single-method interfaces. But there are real, tangible advantages to using lambda expressions in place of more traditional approaches that implement functional interfaces.
Benefits of lambda expressions in Java
Here is a short list of the benefits of lambda expressions in Java.
- Conciseness
- Reduces code bloat
- Readability
- Eliminates shadow variables
- Encourages functional programming
- Code reuse
- Enhanced iterative syntax
- Simplified variable scope
- Less boilerplate code
- JAR file size reductions
- Parallel processing opportunities
To fully understand the benefits and how lambda expressions provide code conciseness and readability, just look at how we used to handle functional interfaces — an interface that only defines a single method. There were basically two approaches. One approach was to define a separate class that implements the interface, while the second was to use an anonymous inner class.
Single class approach to interfaces
The first approach — using a separate class to implement the Comparator interface example from a prior lambda functions article — would look like this:
The benefit to this approach is the ability to share the new class among multiple code bases, so reuse is possible. The disadvantages to the single class approach? For starters, there is code bloat. You need a whole new class to implement a single method. Furthermore, the logic is separated from the point in which it is needed. This will make troubleshooting and code maintenance more difficult. To address the shortcomings of this approach, Java 1.1 introduced the concept of anonymous inner classes.
Benefits and drawbacks to anonymous inner classes
An anonymous inner class allows developers to define and implement a functional interface at the point in the code where it is needed. In the prior example, we needed to create a separate class named MyComparator. With anonymous inner classes, you don’t define a separate class, you simply implement the methods it requires — thus the name anonymous. Here’s how the Comparator example looks when implemented with an anonymous inner class.
Anonymous inner classes are popular and much preferred over creating separate implementing classes. They also allow for the implementing code to be written at the spot in which the code is used, which makes troubleshooting and long-term maintenance easier.
There are drawbacks to anonymous inner classes though. One major drawback is that the code does not look pretty. If anything, it looks bloated. Furthermore, the code isn’t very reusable. There’s no way to invoke an anonymous inner class from outside of the code in which it is defined. And a more innocuous issue is the peculiar variable scope they introduce directly within a class. Variables defined outside of an inner class do not employ the traditional rules pertaining to block scope within a Java class. As a result, it is easy to fall prey to a bug-inducing anti-pattern known as variable shadowing. This can create bugs that are very difficult to troubleshoot.
Lambda expression benefits and drawbacks
With lambda expressions, the goal is to minimize as many of the drawbacks to using a single class or anonymous inner class when we implement a functional interface. At the same time, we want to maximize the benefits. If you look at the Comparator example implemented with a lambda expression in Java, you can’t debate that the code is much more concise and compact.
Furthermore, there is no potential for variable shadowing with lambda expressions. This eliminates a major downside with inner classes. We should also note that even inner classes create a new .class file when the application is packaged and deployed, which doesn’t happen with lambda expressions. This provides the minor benefit that the deployment artifacts that get created are marginally more compact.
This simple example of lambda expressions is only sufficient to demonstrate a few of the benefits of lambda expressions in Java as compared to other approaches. As you explore lambda expressions at a more advanced level, you will discover how they also make iterative processing easier using the new, functional forEach method. And because lambda expressions can be assigned to a variable, they provide an opportunity for reuse that simply isn’t possible with anonymous inner classes.
It took a long time for lambda expression to finally make it into the Java language, but given the benefits of using lambda expressions in Java code, it’s no wonder that developers are excited when their target deployment platform gets upgraded to a newer version of the JDK.
The code for these Lambda expressions in Java can be found on GitHub.