About Johannes Thones

Johannes is a Software-Developer, ThoughtWorker, Permanent Journeyman, Ruby Enthusiast, Java and Devils Advocate. He lives and works in Hamburg, Germany.

Java 8: Testing the Lambda Water

Java 8 is about a year away and comes with a language feature I really look forward to: Lambda Expression. Sadly the other big feature, Modules for the Java Platform, has been delayed to Java 9. But nevertheless, bringing lambda expressions (or closures if you like) into the language will make programming in Java much better.

So nearly one year to go – but as Java is developed open source now, we can have a look and try to use it right now. So let’s go!

Download and Install Lambda enabled Java 8

First, I expected that I have to compile Java 8 myself, as it has not yet been release. But I was pleasantly surprised to see, that there are binary build available for all platforms at http://jdk8.java.net/lambda/. So I just downloaded the latest developer preview build and installed it on my computer.

To make sure it works, I created an LambdaIntro class containing a “Hello, World!”, compiled and executed it:

~ $ export JAVA_HOME=~/Devtools/Java/jdk1.8.0/
~ $ cd spikes/lambda-water
~ $ $JAVA_HOME/bin/javac  src/net/jthoenes/blog/spike/lambda/LambdaIntro.java
~ $ $JAVA_HOME/bin/java -cp src net.jthoenes.blog.spike.lambda.LambdaIntro
Hello from Java 8!

Note: I use the command-line to compile and execute here, because IDEs do not support Java 8 as of now.

The Non-Lambda Way

As an example lets assume I want to loop through a list of objects. But for my business logic, I need to have the value and the index of the list item. If I want to do it with current Java, I have to handle the index together with the actual logic:

List list = Arrays.asList('A', 'B', 'C');
for (int index = 0; index < list.size(); index++) {     String value = list.get(index);     String output = String.format('%d -> %s', index, value);
    System.out.println(output);
}

This will output

0 -> A
1 -> B
2 -> C

This is not too bad, but I did two things in the same few lines of code: controlling the iteration and providing some (very simple) business logic. Lambda expressions can help me to separate those two.\

The eachWithIndex method signature

So I want to have a method eachWithIndex which can be called like this:

List list = Arrays.asList('A', 'B', 'C');
eachWithIndex(list,
    (value, index) -> {
        String output = String.format('%d -> %s', index, value);
        System.out.println(output);
    }
);

The method receives two parameter. The first one is the list and the second one is a lambda expression or closure which instructs the method what to do with each list item. As you can see in line 3, the lambda expression receives two argument: the current value und the current index. These arguments do not have a type declaration. The type information will be inferred by the Java 8 compiler. After the arguments, there is a -> and a block of code which should be executed for every list item.

Note: You will have to write this method in a normal text editor or ignore the error messages inside your IDE.

Implement the eachWithIndex method

To use a lambda in Java 8, you need to declare a functional interface. A functional interface is an interface which has exactly one method – the method which will be implemented by the lambda expression. In this case, I need to declare a method which receives an item and an index and returns nothing. So I define the following interface:

public static interface ItemWithIndexVisitor<E> {
    public void visit(E item, int index);
}

With this interface I can now implement the eachWithIndex method.

public static <E> void eachWithIndex(List<E> list, ItemWithIndexVisitor<E> visitor) {
    for (int i = 0; i < list.size(); i++) {
         visitor.visit(list.get(i), i);
    }
}

The method makes use of the generic parameter <E>, so the item passed to the visit method will be inferred to be of the same type than the list.

The nice thing about using functional interfaces is, that there are a lot of them already out there in Java. Think for example of the java.util.concurrent.Callable interface. It can be used as a lambda without having to change the code which consumes the Callable. This makes a lot of the JDK and frameworks lambda enabled by default.

Using a method reference

One little handy thing coming from Project Lambda are method references. They are a way, to re-use existing methods and package them into a functional interface object. So let’s say I have the following method

public static <E> void printItem(E value, int index) {
    String output = String.format('%d -> %s', index, value);
    System.out.println(output);
}

and I want to use this method in my eachWithIndex method, than I can use the :: notation inside my method call:

eachWithIndex(list, LambdaIntro::printItem);

Looks nice and concise, doesn’t it?

Summary

This makes my first lambda example run. I couldn’t avoid a smile on my face to see closures running in one of my Java program after longing for them so long. Lambda Expression are currently only available as a developer preview build. If you want to find out more, read the current Early Draft Review or go to the Project Lambda project page.

I uploaded the full example code to gist.

Reference: Java 8: Testing The Lambda Water from our JCG partner Johannes Thoenes at the Johannes Thoenes blog blog.

Related Whitepaper:

Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions

Get ready to program in a whole new way!

Functional Programming in Java will help you quickly get on top of the new, essential Java 8 language features and the functional style that will change and improve your code. This short, targeted book will help you make the paradigm shift from the old imperative way to a less error-prone, more elegant, and concise coding style that’s also a breeze to parallelize. You'll explore the syntax and semantics of lambda expressions, method and constructor references, and functional interfaces. You'll design and write applications better using the new standards in Java 8 and the JDK.

Get it Now!  

One Response to "Java 8: Testing the Lambda Water"

  1. Zed says:

    This would be one line in java 8 (:p)
    list.forEach((item)-> System.out.println(String.format(“%d -> %s”, list.indexOf(item),item)));

Leave a Reply


eight + 7 =



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close