Using Java 8 Lambdas to implement simple transformations – Part 1

Spread the love

If you are not used to functional programming, or have been coding in prior Java versions for a long time now, it is somewhat a mixed feeling when you read about Java 8 Lambda features or when you look at Java 8 code utilising the Lambda feature. Obviously, reading about it makes you feel like you should right away start using it , however, as soon as you start to think about using it, you are somewhat lost of how and where can you really leverage it. Sometimes, it can be daunting for even a seasoned Java programmer to start applying this newly acquired Java 8 Lambda knowledge, since we are not used to that style of coding (and thinking).

This blog tries to demonstrate one of the many use cases of Java 8 Lambda – Transformations. I plan to use a simple example that I am sure most of us might have come across in pre-Java 8 world, so looking at how Java 8 Lambda makes coding for that use case a piece of cake is something I hope to demonstrate through this blog.

Alright, lets bite the bullet right away.

How many times have you been in a situation where you have a Collection of some custom Java object (say Employee objects) and some part of your code needs a collection of all the employee names (or some other attribute within the Employee class). Sounds familiar….this is such a common use case and happens all the time.

So what do we do to solve this in the pre-Java 8 world. Here is a list of steps…

  • Declare a new collection of the required Type – i.e of the Type of the required Employee attribute (Say Collection in case of the attribute being Name)
  • Loop over the Employee collection, preferably using an iterator
  • For each Employee, get the name, add it to the new Names collection

Here is how the code looks like.

The above code is more of a syntactic sugar of what code gets executed under the hood, a sample of which is shown below.

And if you are a clean code programmer, you may do all of this in a separate method, that accepts the Employees collection, and returns the new Names collection.

And now, if you need a collection of some other attribute of the Employee class, say employee Id, you copy paste the same piece of code (or method), replacing name with employee Id.

Now, lets try to achieve the same result as described above using Java 8.

Simple and sweet…isn’t it!!!

So, here goes the explanation…

  • We start with the employees collection.
  • Get a stream from the collection. A stream is a similar to an iterator, in that, it lets you iterate through elements of the input collection, however the iteration itself is managed internally. So, the next operation we request to perform on a stream gets performed on every element returned by the stream.
  • The next operation is a mapoperation that lets us transform – As you may observe, we use Lamdba to describe our transformation – i.e. Accept an employee object as an input, and return employee name as the output.
  • The next operation is to collect the output elements into an output collection. So in this case, we specify the output to be a List and everything else about declaring and defining a new list, adding elements to it is taken care off internally.

One may feel that the Java 8 version is more fancier than our original pre-Java 8 code and is probably just a syntactic sugar over the pre-Java 8 code. However there are some serious benefits with the Java 8 code. Here is a a few important benefits to take note of.

Iteration is managed internally

As you can observe, we do not have to write code to govern how the iteration should happen, we do not have to evaluate if we have elements in the collection to iterate, we do not have to calculate if we have reached the last element, and so on. We just say that we need a stream of elements from the input collection. So a lot of things get taken care of by the underlying implementation, which is obviously beneficial – lesser the code we write, lesser the potential to make errors. It also opens up a lot of new optimisation opportunities for the underlying implementation. For example, if we use parallelStream() instead of the stream() call, the underlying platform can leverage multiple threads to perform this operation. This might be useful in certain cases where the operation is happening on a large number of elements.

Resultant List is managed internally

The resultant list is created by the underlying implementation of the Collectors.toList() method. One may think this is probably not a big deal since in the pre-Java 8 code, this is done by a single call to new ArrayList(). However, some deep thought into it would make it clear that we are relieved of the responsibility of the management of the resultant list. That means, we do not have worry about that List is just declared, or it is defined (initialised) as well. Thus, we do not have to worry about the NullPointerException we would have got for the case where we forget to initialise the resultant list with new Arraylist() call in our pre-Java 8 version of the code.

Similarly, since the creation and population of the resultant List is managed by the underlying implementation, we need not worry about concurrency cases that may arise in case the List creation if managed by us as in the pre-Java 8 version.

Resultant List is immutable

This is probably the biggest benefit of Java 8 code. The resultant list is immutable, so the caller does not have a way to alter it before or during the transformation. This is obviously not the case with the pre-Java 8 version, where the resultant list could be altered in between.

Clear, Concise and Crisp Code

In addition to the above outlined (somewhat hidden) benefits, the obvious visible benefit is very easy to understand single line of code, clearly stating the intent of the operation in a clear and concise manner.

Alright, so we have reached the end of this part of this blog series, where I intended to cover a simple example on how to leverage Java 8 Lambda’s to implement simple transformations on collections and demonstrate the hidden benefits and power of use of Java 8 features like Lambda, Collectors, Streams over the traditional approach. I hope to cover more about transformations in subsequent blogs in this transformation series.

I hope you enjoyed reading the blog. As always, would love to hear any feedback you may have.

Happy learning!!



Spread the love


Leave a Reply

Your email address will not be published. Required fields are marked *