Introduction to JDK8, Lambdas and Functional Interfaces

In this blog, I will give you a quick introduction to the upcoming version of Java, showing you simple examples of how to use the most important feature in JDK8; lambda expressions.

Very recently I attended a presentation about JDK8 and since then my thoughts about functional programming has totally changed. For me, it looked like a complex mathematical expression with a really high learning curve, but now I think that it will actually help developers write better and more effective code. People who still not believe that functional programming will not disappear are mistaken and not trying to learn these concepts will make it harder to keep up with the development of Java. The good news is that it is much easier to learn functional programming with JDK8 since the functionality and syntax is simpler than Scala for instance.

Scala is still a very interesting language, but again, one might ask how it will be maintained and developed in the future. One of the biggest advantages of JDK8 compared to Scala is the JavaDoc, which is far more better and easier to read. I even think that many developers will chose JDK8 just because of the JavaDoc. Developers already using Scala, however, will most probably not switch and the reason for this is very simple. Many of the features in JDK8 is very similar to the ones in Scala and it still has a ton of other features (Traits, Actors, for-comprehensions and more powerful control structures (case-class matching) just to mention a few things) that JDK8 might not support in a very long time. Scala is still more powerful language compared to the current version of the JDK8 which is still under development, however, the differences might be less when JDK8 is released sometime next year.

Updates in JDK8

Project Lambda, also called JSR-335, is the main focus for the JDK8. It has be in development since the end of 2009 and is currently planned for release in spring 2014. There is in addition to JSR-335 many updates and new features in the existing libraries. Here is some interesting ones:

– A new Date&Time API. The new API is called ThreeTen (derived from JSR-310)and is not JodaTime as mange would think. JodaTime has several design flaws (see [3]). The new API seems simpler to use (see [4])
– “Prepare for Modularization” – updates that prepare Java and developers for future modularization.
– The Collection-API will be extended with “Bulk Data Operations”, that is operations like filter/map/reduce. This is typical things that you’d only get in libraries like Google Guava [2].
– Several core packages in java.lang and java.util will be updated
– Reduction of memory usage without affecting performance.
– Base64 encoding and decoding. Typically used when working on HTTP data transfer.
– Stronger crypto algorithms (NSA, SHA, PBE)
(see [1] for more updates)

“Lambda Expressions”

The functional side of the JDK8 is probably the biggest update to the Java language since the Performance-update in version 1.2 and Generics in version 1.5. It is also seems to be very important for Java’s journey in the years to come. Let take a recap on some important concepts:

– Lambda: an anonymous function
– Closure: a function that has some kind of reference to its environment
– Higher Order Function: a function that takes or returns a function

With the help of lambda expressions we can now reduce the code to its most essential tasks. This example

button.addActionListener(new ActionListener() {
 public void actionPerformed(ActionEvent e) {
     button.setText("Go away");
 }
});

can now be effectively written as

button.addActionListener( (ActionEvent e) -> button.setText("Go away") );

or just as

button.addActionListener( e -> button.setText("Go away") );

Here’s an example with Thread:

Thread thread = new Thread( new Runnable() {
 public void run() {
   System.out.println("jdk8");
 }
});

The same code using JDK8:

Thread thread = new Thread( () -> System.out.println("jdk8") );


“Functional Interface”

The basic building blocks of functional programming in JDK8 is in something called Functional Interfaces. New in Java 8, is the package java.util.function and this package contains a number of interfaces that together is the basis of many of the additions in JDK8. In this section, I will only show you a small portion of the function-package. I will show you how to use two of the functional interfaces called Function and BinaryOperator. In order to understand how they work, we have to take a closer look at Lambdas. In its simplest form, a lambda could be written like this:

(arguments) -> operation

All interfaces that contains only one abstract method, is in JDK8 called a Functional Interface. The one abstract method itself is called a Single Abstract Method (or SAM for short) and can be named anything. The important thing to remember in JDK8, is that the SAM-method can be overridden by a lambda using only the exactly the same type and number of arguments as the SAM-method. Since Java already has a lot of interfaces having only method, all of these will be forward-compatible. In order words, they are automatically functional in JDK8. An example of this is the Runnable-interface:

public interface Runnable {
  public abstract void run();
}

In JDK8 the Runnable interface is exactly the same except that is has an additional annotation:

@FunctionalInterface
public interface Runnable {…

Runnable is a functional interface with a SAM, so the expression () -> System.out.println(“jdk8″) is automatically turned into new Runnable() {…}. Since the run-method doesn’t take any arguments, is not necessary nor possible to define any arguments on the left side of the -> symbol. In the next examples, however, we’ll look at two functional interfaces having respectively one and two input-arguments.

A function for calculating a square root of some number could be written as:

Function<Integer, Integer> sqr = n -> n * n;

This definition says that we must take in a Integer-argument and then return a Integer-argument. This is true with respect to SAM-methods definition in interface Function:

@FunctionalInterface
public interface Function<T, R> {
  public R apply(T t);
}

Further, this lambda could be used to calculate the square roots of all the numbers in a list like this (done using map/filter/reduce bulk operations in the new Collection API):

List list = Arrays.asList(1,2,3,4,5);
List squareroots = list.stream().map(sqr).collect(Collectors.toCollection( () -> new ArrayList() ));
squareroots.forEach(n -> System.out.print(n + ", "));

A lambda for calculating the sum of two numbers, can be written as:

(int a, int b) -> a + b

We can then use this lambda like this:

BinaryOperator sum = (a, b) -> a + b;

This definition makes us able to use the sum-lambda directly or send it into other lambda functions that takes an lambda as one of its arguments (just as in the square root example above). If you don’t need to reuse the lambda, then you should just code the lambda as an anonymous function.

Here’s an example of how to calculate the sum of all the numbers in a list:

int t = list.stream().reduce( (a, b) -> a + b ).get();
System.out.println(t);

The lambda could also be called directly (you can still use the interface like before):

System.out.println(sum.apply(1,2));


“Internal Iteration”

One of the key benefits of JDK8, is that you can focus on what to do and not how to do it. The Collections API in the JDK8 is now much more powerful and one of the new features is functional iterations.

for (Shape s : shapes) if (s.getColor() == RED) s.setColor(BLUE);

In JDK8, we can rewrite this loop into:

shapes.forEach( s -> if (s.getColor() == RED) s.setColor(BLUE) );

It apparently looks like just a syntactical change, but the difference is that in the functional example, it is the API that is responsible for doing the iteration. While the normal loop is sequential, the API-developers is free to use parallelisation, laziness and several other techniques to makes your functional code more powerful by avoiding sequential handling of the data when such handling is not necessary. The latter is relevant when doing CPU optimization (see [5] for more info).


Conclusion

This article only scratched the surface of JDK8. Below there is some resources you can look at to learn more about lambdas in JDK8. JDK8 with lambdas can be downloaded from http://jdk8.java.net/lambda/. To test, download and unzip the JDK and then add it to your favourite editor. I strongly advise using IntelliJ which has a impressing support for Java8 and its new features.


References:

[1] http://openjdk.java.net/projects/jdk8/features
[2] https://code.google.com/p/guava-libraries/
[3] http://blog.joda.org/2009/11/why-jsr-310-isnjoda-time_4941.html
[4] http://java.dzone.com/articles/introducing-new-date-and-time
[5] http://en.wikipedia.org/wiki/Out-of-order_execution

Recommended reading:
http://java.dzone.com/articles/devoxx-2012-java-8-lambda-and
http://java.dzone.com/articles/java-%E2%80%93-far-sight-look-jdk-8
http://www.dalorzo.org/2012/11/what-is-type-of-lambda-expression.html
http://blog.sanaulla.info/2013/03/16/extracting-the-elements-of-the-java-collection-the-java-8-way/

JavaDoc – java.util.function
http://download.java.net/lambda/b83/docs/api/java/util/function/package-summary.html

This entry was posted in Java and tagged . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>