Pages

Wednesday, November 28, 2012

Java 8 - Closures, Lambda Expressions Demystified

Project Lambda, Closures - JSR 335 (Part 1)
Lambda Expressions are probably one of the most interesting changes of the Java Language. They will add totaly different syntactical elements like the Arrow Operator, Method References, Defender Methods etc. Java gains functional aspects to reduce verbosity and improve parallel processing and stability.

Why Lambda
We all know Java Language is an object oriented programming language and we are using it with passion. But sometimes we want to pass some code to a method instead of an object. To make this happen we are implementing Callbacks. This leads us to develop verbose code and it feels not like to be well supported by Java. An additional use case is dealing with groups of data. Sometimes it is necessary to execute a specific algorithm to a group of data. Functional programming langues support things like "forAllDo". In Java you need to implement that by yourself or have to use some utility classes from third party libraries. This might be verbose and creepy.
Java 8 Blog Series

   1. Closures, Lambda Part 1 - Demystified
   2. Closures, Lambda Part 2 - Deep dive
   3. Project Jigsaw
   4. Date and Time API
   5. Annotiations, Checker Framework
   6. Concurrent Collection Framework

Setting Up Lambda
Because the development of Java 8 has not finished yet and the IDE Support is in an rudimental state, I recommand following environment set-up:

Download

Proceed following steps to set up your environment and run Java 8:
  1. Download NetBeans and Java 8 (use Links above)
  2. Unzip NetBeans and Java 8 JDK
  3. Run NetBeans (with command line param: --jdkhome YourJava8Dir)
  4. Check if your sources compile in java8

At the following I want to give you a short overview what is possible with Closures and Lambda Expressions. After that I will explain Lambda systematically to show up what happends behind the scenes.

Part 1: Lambda in Action

Anonymous Inner Classes

Classic approach
At the following snippet you can see how we use Anonymous Inner Classes in Java all the time. Adding an ActionListener to an UI Element is an usual use case. NetBeans shows a big warning: This anonymouse inner class creation can be turned into a lambda expression. If you press Alt+Enter to fix it, NetBeans will convert the source code into a lambda expression.

The Lambda way
By using lambda the source code looks like this: Notice that our code is les verbose. Furthermore it is not necessary to import "java.awt.event.ActionListener" any more. Moreover it is possible to get rid of class casting and some verbosity by using type inference: The Type of "ae" depends on the context in which it appears (Target Typing). That allows us to delete the import of "java.awt.event.ActionEvent" and we are happy to see a little less dependency. I explain more about the SAM-Types and what happens there later.
 
Method References

Lambda Expressions provide far more than dealing with anonymous methods. It is possible to adress the invocation of static and non static methods by using "::" operator.

Static methods
Non static methods
Arrays.sort will invoke the compareTo method of myObj because it has the reference of that method.
 
Virtual Extension Methods

Extension Methods alias Defender Methods alias Default Methods exists to integrate the new previous introduced features of Java 8 into Java 7 and grant backwards compatibility. All the functional features would have no use if we could not find them as a part of Java langauge core, so there has to be a way to change things like the Collection-Framework but ensure same behavior in legacy code without compile errors. Virtual Extension Methods are highly discussed because of an insane impact to the language. (e. g. interfaces with method bodys)
List is an well known interface and it became again an victim of Java language extensions. Besides some confusing abstract wildcard generic types, we can find method bodys within the interface definition. So what tells us the code now? We now have an optional implementation contract between interfaces and classes, like we have in abstract classes with implemented methods. Every implementation of List has the opportunity to overwrite "sort" but it is not obligatory. This is by far the most strange language extension of Java I have seen so far. I understand that such abominations are necessary for compatibility reasons. However I feel bad to see the highest abstraction level becomming a concrete implementation.
 
JDK integration and improvement  
 
JDK improvement starts in "java.util.functions". You can see the current content of the package at the right image. I picked some interesting interfaces that I discuss briefly.

BinaryOperator.class - combines two operands
Mapper.class - maps from class a to class b (within a chain)
Predicate.class - determines if the input object matches some criteria
Besides new packages and classes Lambda Expressions will improve existing code. Probably the collection framework will change a lot. A functional way of handling groups of data could be a big advantage. Less verbose code leads to more stability and functional processing without sideeffects makes parallel processing much easier.

Example: Collection.removeAll (with filter) Lambda way to use That's it for now. I hope you enjoyed my first part of my Java 8 Blog series. Please notice that "Lambda Part 2: Deep Dive" is currently in work. I will publish as soon as I can. I will show you some technical specifications, rules and compiler behavior to make the demystification perfect. So long.

Java 8 Blog Series

15 comments:

  1. Replies
    1. May be, but I really love these features. Java 8 lambda expression and Streams will give Java coding a new direction for sure.

      Delete
  2. Absolutely, it's including just a few of the features leveraged so far by third party APIs (like Jakarta Commons Collections) and borrowing Groovy syntax for closures. Jigsaw it's just an attempt to implement some kind of OSGi architecture into the JVM. Nothing new, and less powerful and comprehensive. Just a little evolving for the Java platform, nothing revolutionary.

    ReplyDelete
    Replies
    1. just a little - can pile up to make a big difference :-)

      Delete
  3. Java is trying to create its own way that different than C#, but it makes Java uglier than before. I thought Oracle devs will improve generics first, but seems they have different priorities.

    ReplyDelete
    Replies
    1. Also a passy by ref. would have been good idea.

      Delete
  4. i am so sad that jigsaw will not be in java 8

    ReplyDelete
  5. @JHood: Java becomes C++

    ReplyDelete
  6. No, pass by ref would be creepy.

    ReplyDelete
  7. Where we at with part 2? I'm chomping at the bit!

    ReplyDelete
    Replies
    1. I am little bit behind and try to proceed with this series as soon as possible! ;-)

      Delete
  8. Very help tutorial Frank, nicely done. By the way, I have also shared couple of Java 8 lambda expression examples, which may be handy to Java developers starting up with Java 8. Let me know, if you find it helpful. Thanks

    ReplyDelete
  9. Moving from JDK 6 and 7 to Java 8 is interesting because Java 8 is very much different from lower versions just because of lambda. We can perform almost a business logic in a single line. That's really great.

    ReplyDelete