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.
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.
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:
Proceed following steps to set up your environment and run Java 8:
- Download NetBeans and Java 8 (use Links above)
- Unzip NetBeans and Java 8 JDK
- Run NetBeans (with command line param: --jdkhome YourJava8Dir)
- 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
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.
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.
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
|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|
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|