Mar 19, 2015

Java 8 and lambdas : ooooh, that's how it works, then.


Disclaimer: several people "complained" about this code being overly complicated & verbose. Trust me, I did it on purpose to illustrate what many legacy Java apps look like these days. Hopefully lambdas can help us clean up some of the mess that has accumulated over the years. Read on!

One of the key new features of Java 8 is the introduction of functional programming and lamba expressions. This article will give you a real-life example of how lambas can be introduced in existing code, reducing verbosity and increasing flexibility... or so they say ;)

All code for this article is part of a larger repository available at:
github.com/juliensimon/SortAndSearch

Let's get started. Imagine you had to code a linear search method for lists, which could apply different policies when an element has been found:
  • move the element to the front of the list (aka "Most Recently Used"),
  • move it to the back of the list (aka 'Least Recently Used"), 
  • move it one position closer to the the front of the list.

After some experimentation ("Cut and paste ? Yuck. Anonymous classes ? Meh!"), you would realize that these policies only differ by a couple of instructions and that there's an elegant way to factorize them nicely: behavior injection.

Surely, you would get something similar to:
  • A linearSearch() method implementing the Strategy pattern through an object implementing the LinearSearchMode interface,
  • A LinearSearchMode interface defining a single method in charge of performing the actual move,
  • Three LinearSearchModeXXX classes implementing the interface for each move policy,
  • A LinearSearchModeFactory class, implementing the Factory pattern to build LinearSearchModeXXX objects while hiding their internals.

Here's the corresponding code. Pretty canonical, I guess.



You would use the whole thing like this:

linearSearch(list,t,LinearSearchFactory.build(LinearSearchFactory.modeMoveFirst)

Looks familiar? Yeah, thought so ;) Now, although this is pretty neat and tidy, this is awfully verbose, isn't it? There's a lot of boilerplate code and technical classes just to change of couple of lines of code. So yes, we did avoid cut-and-paste and code duplication, but in the end, we still had to write quite a bit of code. For lazy programmers, this is always going to be a problem :)

And so, tada! Lambda expressions.You can read the theory elsewhere, here's what it means to our code:
  • No change to our linearSearch() method,
  • No change to our LinearSearchMode interface,
  • No more need for LinearSearchModeXXX and LinearSearchModeFactory, which is great because they really added nothing to the logic of our application.
All you have to do, then, is to replace the mode parameter in linearSearch() with a lambda expression implementing the move policy :

Pretty nerdy, huh? I like it. Less code, less bugs, less problems, more sleep! Adding another move policy would only mean adding a couple of lines, so less verbosity and more flexibility indeed.

For the record, let me say that I've always avoided functional languages like the plague (shoot me). I don't expect this to change in the near future, but I have to admit that the introduction of lambdas in Java 8 does solve a number of problems, so there. I'll keep digging :)

That's it for today. Till next time, keep rockin'.