Using Apache Commons Functor functional interfaces with Java 8 lambdas

Apache Commons Functor (hereon [functor]) is an Apache Commons component that provides a functional programming API and several patterns implemented (visitor, generator, aggregator, etc). Java 8 has several nice new features, including lambda expressions and functional interfaces. In Java 8, lambdas or lambdas expressions are closures that can be evaluated and behave like anonymous methods.

Functional interfaces are interfaces with only one method. These interfaces can be used in lambdas and save you a lot of time from writing anonymous classes or even implementing the interfaces. [functor] provides several functional interfaces (thanks to Matt Benson). It hasn't been released yet, but there are some new examples in the project site, in the trunk of the SVN. I will use one of these examples to show how [functor] functional interfaces can be used in conjunction with Java 8 lambdas.

After the example with [functor] in Java 8, I will explain how I am running Java 8 in Eclipse (it's kind of a gambiarra, but works well).

Example using Apache Commons Functor

Here is a simple example with one Predicate.

List<Integer> numbers = Arrays.asList(1, 2, 3, 4);

UnaryPredicate<Integer> isEven = new UnaryPredicate<Integer>() {
    public boolean test(Integer obj) {
        return obj % 2 == 0;
    }
};

for( Integer number : numbers ) {
    if (isEven.test(number)) {
        System.out.print(number + " ");
    }
}

It prints only the the even numbers, those that pass by the predicate test.

Example with Java 8 lambdas

This modified version is using Java 8 lambdas

List<Integer> numbers = Arrays.asList(1, 2, 3, 4);

UnaryPredicate<Integer> isEven = (Integer obj) -> { return obj % 2 == 0; };
 
for( Integer number : numbers ) {
    if (isEven.test(number)) {
        System.out.print(number + " ");
    }
}

The behaviour is the same. UnaryPredicate is a functional interface. Its only method is boolean test(A obj);. And when used in a lambda expression you just have to provide the right number of arguments and implement the closure code.

The difference in the two code snippets are the way that the UnaryPredicate for even numbers is created. Below you can see the two ways of creating this predicate, with and without Java 8 lambdas.

// pre-java-8
UnaryPredicate isEven = new UnaryPredicate() {
    public boolean test(Integer obj) {
        return obj % 2 == 0;
    }
};

// with lambda-8
UnaryPredicate isEven = (Integer obj) -> { return obj % 2 == 0; };

Java 8 in Eclipse

Eclipse 8 doesn't support Java 8, so you have to create a new builder in order to have Eclipse compiling your project's sources. For a complete step-by-step guide on how to set up Eclipse Juno and Java 8, please refer to http://tuhrig.de/?p=921. I will summarize the steps here, and will show how to include [functor] jar to the project classpath.

You have to include [functor]'s jar, as well as its dependencies. For the sake of convenience, I used maven-assembly-plugin to generate a jar with dependencies for [functor]. The code and the jar are available from this GitHub repository. Or if you prefer generate your own [functor] jar with dependencies, check out the code from the repository as below.

svn checkout https://svn.apache.org/repos/asf/commons/sandbox/functor/trunk/ commons-functor

And finally include the following to [functor] pom.xml before running mvn clean assembly:assembly.

<plugin>
  <artifactId>maven-assembly-plugin</artifactId>
  <version>2.3</version>
  <configuration>
    <descriptorRefs>
      <descriptorRef>jar-with-dependencies</descriptorRef>
    </descriptorRefs>
  </configuration>
</plugin>

Thanks for your time, hope you enjoyed it! :-)

Categories: Blog

Tags: Apache Software Foundation, Java, Functional Programming