Aspects of Functional Programming in Java

July 16th, 2012 by

Functional programming is a trending topic these days and a lot of Java programmers are hot for the features that modern functional programming languages might offer.

Waiting for Java 8 and native closure support is a nice thing but for now we’re going to take a look at several Java frameworks that are trying to implement typical structures from those functional languages where possible using the capabilities of the Java language to emulate elements like higher-order-functions, closures, options and others …


 

lambdaj

Lambdaj is a framework that calls itself  a library to “manipulate collections in a pseudo-functional and statically typed way” and it indeed offers a nice API to apply conversions, filtering, sorting, grouping, indexing, extractions and aggregations on java collections.

More detailed examples and documentation for lambdaj can be found on the project’s website.

Maven Dependency

We need to add the following one dependency to our pom.xml to work with lambdaj:

<dependency>
    <groupId>com.googlecode.lambdaj</groupId>
    <artifactId>lambdaj</artifactId>
    <version>2.3.3</version>
</dependency>

Preparation

The following class will be used in several following examples  to perform filtering, conversions, aggregations and other stuff with it ..

package com.hascode.sample;
 
import java.util.Date;
 
public class Book {
 private final String title;
 private final Date published;
 private float price;
 
 public Book(final String title, final Date published) {
 this.title = title;
 this.published = published;
 }
 
 public String getTitle() {
 return title;
 }
 
 public Date getPublished() {
 return published;
 }
 
 public float getPrice() {
 return price;
 }
 
 public void setPrice(final float price) {
 this.price = price;
 }
}

Handling Collections like single Objects

In the following example we’re setting the price for each book in the collection using forEach and the normal setter.

package com.hascode.tutorial;
 
import static ch.lambdaj.Lambda.forEach;
import static ch.lambdaj.Lambda.joinFrom;
import static ch.lambdaj.Lambda.on;
import static ch.lambdaj.Lambda.sort;
import static java.util.Arrays.asList;
 
import java.util.Date;
import java.util.List;
 
public class LambdajExamples {
 public static void main(final String... args) {
 List<Book> books = asList(new Book("Some book", new Date(123)),
 new Book("Another book", new Date(456)), new Book(
 "I luv codin", new Date(789)));
 // treating a collection like a single object
 forEach(books).setPrice(10.0f); // sets the price on all objects
 System.out.println(books.get(0).getPrice()); // output: 10.0
 System.out.println(books.get(1).getPrice()); // output: 10.0
 System.out.println(books.get(2).getPrice()); // output: 10.0
 }
}

Sorting by Object’s Fields

We’re reusing the list of books from the example above. First we’re sorting the list on the book’s publication date in the second example we’re sorting the list on the title.

 // sorting the books by publication date
 List<Book> booksByDate = sort(books, on(Book.class).getPublished());
 System.out.println(booksByDate.get(0).getTitle()); // "output: Some book"
 System.out.println(booksByDate.get(1).getTitle()); // "output: Another book"
 System.out.println(booksByDate.get(2).getTitle()); // "output: I luv coding"
 
 // sorting the books by title
 List<Book> booksByTitle = sort(books, on(Book.class).getTitle());
 System.out.println(booksByTitle.get(0).getTitle()); // "output: Another book"
 System.out.println(booksByTitle.get(1).getTitle()); // "output: I luv coding"
 System.out.println(booksByTitle.get(2).getTitle()); // "output: Some book"

The same code in Scala could look like this one:

List(new Book("Some book", new Date(123)),
 new Book("Another book", new Date(456)), new Book(
 "I luv codin", new Date(789))).sort(_.title < _.title).foreach(b => println(b.title))

Aggregating Values into a List of Comma-Separated Values

We’re using the list of books from the first example again here and join the books titles into a string ..

 // create a comma separated list of titles from the books collection
 String titles = joinFrom(books).getTitle();
 System.out.println(titles); // "Some book, Another book, I luv codin"

Searching by an Object’s Field

In the following example, we’re searching for a specific book’s title

// find books with title=Some book
 List<Book> booksWithSpecifiedTitle = select(books,
 having(on(Book.class).getTitle(), equalTo("Some book")));
 System.out.println(booksWithSpecifiedTitle.size()); // output:1
 System.out.println(booksWithSpecifiedTitle.get(0).getPrice()); // "output: 10.0"

Functionaljava

On the one hand, functional java seeks to improve using the Java programming language – on the other hand it serves as a platform to learn functional programming using a well known language: Java.

This library offers the following features as cited from the project’s website on functionaljava.org:

  • Fully operational Actors for parallel computations (fj.control.parallel) and layered abstractions such as parallel-map, map-reduce, parallel-zip.
  • A package (fj.data.fingertrees) providing 2-3 finger trees for a functional representation of persistent sequences supporting access to the ends in amortized O(1) time.
  • Type-safe heterogeneous list (fj.data.hlist) for lists of elements of differing types without sacrificing type-safety.
  • Monadic parser combinators for writing parsers by combining smaller parsers using composition.
  • Conversion of data types to/from standard Java types.
  • Immutable, in-memory singly linked list (fj.data.List).
  • Immutable lazy singly linked list (fj.data.Stream).
  • Array wrapper (fj.data.Array).
  • Optional value — type-safe null (fj.data.Option).
  • Disjoint union data type — compositional exception handling (fj.data.Either).
  • Monoid (fj.Monoid).
  • Functions with arity 1 to 8.
  • Products of 1 to 8.
  • Configurable equality and hash-code for HashMap and HashSet.
  • Natural number data type (fj.data.Natural).
  • Immutable set implementation using a red/black tree.
  • Immutable multi-way tree — aka rose tree (fj.data.Tree).
  • Immutable tree-map using a red/black tree implementation (fj.data.TreeMap).
  • Zipper implementations for streams and trees.
  • Automated specification-based testing framework (fj.test).

These are indeed a lot of features – in the following examples I am trying to demonstrate a few of them ..

Adding the library to a Project

We just need one Maven dependency here to be added to our pom.xml

<dependency>
    <groupId>org.functionaljava</groupId>
    <artifactId>functionaljava</artifactId>
    <version>3.1</version>
</dependency>

Functions of different arity

Functionaljava offers generic classes to provide anonymous functions of different arities (from 1 to 8)  – the last generic class type parameter is the return type the other parameters are mapped as function parameters.

package com.hascode.tutorial;
 
import static fj.data.Array.array;
import fj.Effect;
import fj.F;
import fj.F2;
 
public class DifferentArityFunctionsExample {
 public static void main(final String[] args) {
 F<String, Boolean> endsWithX = new F<String, Boolean>() {
 @Override
 public Boolean f(final String a) {
 return a.endsWith("x");
 }
 };
 
 F2<String, String, Boolean> stringsEqual = new F2<String, String, Boolean>() {
 @Override
 public Boolean f(final String a, final String b) {
 return a.equals(b);
 }
 
 };
 // output: "barx bazx"
 array("foo", "barx", "moo", "bazx").filter(endsWithX).foreach(output);
 }
 
 static Effect<String> output = new Effect<String>() {
 @Override
 public void e(final String a) {
 System.out.println(a);
 }
 };
}

The corresponding code in Scala could be something like this one

List("foo", "barx", "moo", "bazx").filter(_.endsWith("x")).foreach(println);

Array Filtering

In the following example we’re using a function to filter strings from a collection into a new collection.

import static fj.data.Array.array;
import fj.Effect;
import fj.F;
import fj.data.Array;
 
public class ArrayFilteringExample {
 public static void main(final String[] args) {
 final Array<String> a = array("This", "is", "an", "example");
 final Array<String> b = a.filter(new F<String, Boolean>() {
 @Override
 public Boolean f(final String a) {
 return a.matches(".*i.*");
 }
 });
 b.foreach(new Effect<String>() {
 @Override
 public void e(final String a) {
 System.out.println(a);
 }
 }); // output: This is
 }
}

The counterpart in Scala:

List("This", "is", "an", "example").filter(_.matches(".*i.*")).foreach(println)

Applying a function to each element in a list

In the following example we’re manipulating an array of integers by multiplying each element in the list by 1 and sum the results.

package com.hascode.tutorial;
 
import static fj.data.Array.array;
import static fj.function.Integers.multiply;
import fj.Effect;
import fj.F;
 
public class FoldLeftExample {
 public static void main(final String[] args) {
 // multiplies each element in the array with 1 and adds the results
 int result = array(1, 2, 3, 5).foldLeft(multiply, 1);
 System.out.println(result); // 30
 }
}

In the following example we’re using map and an anonymous function F to add 1 to each element in a list of integers and multiply the result by 2.

Finally we’re using another function, Effect to print the elements.

package com.hascode.tutorial;
 
import static fj.data.Array.array;
import static fj.function.Integers.multiply;
import fj.Effect;
import fj.F;
 
public class ApplyingFunctionPerListElementExample {
 public static void main(final String[] args) {
 // adds 1 to each element and multiplies the result by 2
 // output: 4 6 8 12
 array(1, 2, 3, 5).map(new F<Integer, Integer>() {
 @Override
 public Integer f(final Integer a) {
 return (a + 1) * 2;
 }
 }).foreach(new Effect<Integer>() {
 @Override
 public void e(final Integer a) {
 System.out.print(a + " ");
 }
 });
 }
}

Either Example

The Either represents a value from a computation of one of two possible types mapped to the left and right value of the Either instance.

Often the left value represents an exception or error thrown during the computation and the right one the value if no error was thrown.

In the following example in the first execution a NumberFormatException is thrown and either.isLeft() returns true in the second example, no exception is thrown and we’re able to fetch the computation result using either.right().value().

package com.hascode.tutorial;
 
import fj.data.Either;
 
public class EitherExample {
 public static void main(final String[] args) {
 Either<Exception, Integer> result1 = parseInteger("123456h4");
 System.out.println(result1.isLeft()); // true
 System.out.println(result1.left().value().getClass()); // "class java.lang.NumberFormatException"
 
 Either<Exception, Integer> result2 = parseInteger("123456");
 System.out.println(result2.isLeft()); // false
 System.out.println(result2.right().value()); // 123456
 }
 
 private static Either<Exception, Integer> parseInteger(final String string) {
 try {
 return Either.right(Integer.valueOf(string));
 } catch (Exception e) {
 return Either.left(e);
 }
 }
}

Option Example

An option encapsules the result of a computation and represents optional values. In Scala, instances of an Option are either an instance of Some or of None.

In the following example an integer is parsed from a given string .. in the first example, a NumberFormatException is thrown so option.isNone() returns true and option.isSome() returns false.

In the second example no exception is thrown and the opposite is the case – in addition we’re able to fetch the Integer using option.Some().

So what is the advantage of that? On the one hand, we don’t need to handle exceptions directly – on the other hand, to use an Option might give other programmers reading your code a hint that the performed computation might not yield a result and it is necessary to handle that.

package com.hascode.tutorial;
 
import fj.data.Option;
 
public class OptionExample {
 public static void main(final String[] args) {
 Option<Integer> result1 = parseInteger("1234G46");
 System.out.println(String.format("isNone: %s / isSome: %s",
 result1.isNone(), result1.isSome())); // "isNone: true / isSome: false"
 
 Option<Integer> result2 = parseInteger("1234");
 System.out.println(String.format("isNone: %s / isSome: %s",
 result2.isNone(), result2.isSome())); // "isNone: false / isSome: true"
 System.out.println(result2.some()); // 1234
 }
 
 private static Option<Integer> parseInteger(final String string) {
 try {
 return Option.some(Integer.valueOf(string));
 } catch (Exception e) {
 return Option.none();
 }
 }
 
}

There are many other interesting features present in this library so if you’re interested please take a look at the detailed information on the project’s website.

Guava

Guava is the modern version of commons-collections (also described in this article) and offers some helpful APIs for handling collections, caching, primitives support, concurrency libraries, common annotations, string processing, I/O and other stuff.

For a full list of its features please take a look at the project’s website.

Adding Guava to a Project

One Maven dependency needed – here it is:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>12.0</version>
</dependency>

Predicate Example

In the first example, we’re using a Predicate to filter a list of books for books with a publication date >= 2000, in the second example by their author.

package com.hascode.tutorial;
 
import static com.google.common.collect.Lists.newArrayList;
 
import java.util.List;
 
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
 
public class GuavaPredicates {
 
 public static void main(final String[] args) {
 List<Book> books = newArrayList(new Book("Some book", "Arnold Author",
 1998), new Book("Programmers are weird", "Some author", 2011),
 new Book("Another book", "Another author", 2012), new Book(
 "Ye ole book", "Ye authorr", 1711), new Book(
 "Some book - second edition", "Arnold Author", 2010));
 
 Predicate<Book> newerThanYear2000 = new Predicate<GuavaPredicates.Book>() {
 public boolean apply(final Book book) {
 return book.getYearPublished() >= 2000;
 }
 };
 
 Predicate<Book> byAuthorArnold = new Predicate<GuavaPredicates.Book>() {
 public boolean apply(final Book book) {
 return book.getAuthor().equals("Arnold Author");
 }
 };
 
 System.out.println("books published in year 2000 and later");
 System.out.println(Iterables.filter(books, newerThanYear2000)
 .toString());
 
 System.out.println("books by author=Arnold Author");
 System.out.println(Iterables.filter(books, byAuthorArnold).toString());
 }
 
 static class Book {
 final String title;
 final String author;
 final int yearPublished;
 
 public Book(final String title, final String author,
 final int yearPublished) {
 this.title = title;
 this.author = author;
 this.yearPublished = yearPublished;
 }
 
 public String getTitle() {
 return title;
 }
 
 public String getAuthor() {
 return author;
 }
 
 public int getYearPublished() {
 return yearPublished;
 }
 
 @Override
 public String toString() {
 return "Book [title=" + title + ", author=" + author
 + ", yearPublished=" + yearPublished + "]";
 }
 
 }
}

Function / Transformer

In the following example we’re defining a generic function to transform a collection of books into a collection of strings based on the books titles

Function<Book, String> titleTransformer = new Function<GuavaExamples.Book, String>() {
 public String apply(final Book book) {
 return "X " + book.getTitle();
 }
 };
 // outputs:
 // "[X Some book, X Programmers are weird, X Another book, X Ye ole book, X Some book - second edition]"
 System.out.println(Iterables.transform(books, titleTransformer));

Optional

Guava offers a structure to signal that the result of a computation might yield no result – Optional.

In the following example the first computation throws a NumberFormatException and no result is possible – in the second call we’re able to test for valid computation and return the value from the operation. As you might have noticed this approach is similar to the Option of the functionaljava example.

Optional<Integer> computed1 = computeIntegerFrom("1234zzx");
 System.out.println(computed1.isPresent()); // false
 Optional<Integer> computed2 = computeIntegerFrom("12345");
 System.out.println(computed2.isPresent()); // true
 System.out.println(computed2.get()); // 12345
 
[..]
 
private static Optional<Integer> computeIntegerFrom(
 final String numberAsString) {
 try {
 Integer i = Integer.valueOf(numberAsString);
 return Optional.of(i);
 } catch (Exception e) {
 }
 return Optional.absent();
 };

Apache Commons Collection

Though commons collections has no support for generics it is still used or referenced in many projects. There are three features that I’d like to demonstrate here:

  • Closures: Are simple functions that allows us to get a reference to each object in the collection and alter the object
  • Transformers: Enables us to transform data from one format into another
  • Predicates: Similar to the Guava example above the allow us to test each element of a collection to filter a collection

If you’re used to commons collections that much that you do not want to switch to Guava for some of the features please take a look at the collections-generics project on GitHub – it’s an implementation of commons-collections with generics support.

Maven Dependencies

We just need one dependency to integrate commons-collections into our project..

<dependency>
    <groupId>commons-collections</groupId>
    <artifactId>commons-collections</artifactId>
    <version>3.2.1</version>
</dependency>

Predicates to filter Collections

The following example filters a list of books by their title so that all books with a title that does not contain  the string book are filtered from the collection. As you might have noticed – in contrast to Guava without generics we’re forced to work with an object in our predicate.

package com.hascode.tutorial;
 
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
 
import org.apache.commons.collections.Predicate;
import org.apache.commons.collections.iterators.FilterIterator;
 
public class CommonsCollectionExample {
 public static void main(final String[] args) {
 List<Book> books = new ArrayList<Book>();
 books.add(new Book("Some book", new Date(123)));
 books.add(new Book("Another book", new Date(456)));
 books.add(new Book("I luv codin", new Date(789)));
 
 Predicate titlePredicate = new Predicate() {
 public boolean evaluate(final Object obj) {
 return ((Book) obj).getTitle().matches(".*book$");
 }
 };
 
 @SuppressWarnings("unchecked")
 Iterator<Book> booksIterator = new FilterIterator(books.iterator(),
 titlePredicate);
 while (booksIterator.hasNext()) {
 System.out.println(booksIterator.next().getTitle());
 }
 // output:
 // Some book
 // Another book
 }
}

Closures

We’re recycling the book list from the example above and we’re applying a closure to each element of the collection that print’s the books title:

Closure closure = new Closure() {
 public void execute(final Object obj) {
 Book book = (Book) obj;
 System.out.println("the book's title is: " + book.getTitle());
 }
 };
 CollectionUtils.forAllDo(books, closure);
 // the book's title is: Some book
 // the book's title is: Another book
 // the book's title is: I luv codin

Transformer

First of all we’re recycling the list of books and the title-printing-closure from the examples above – second we’re applying a transformer on the collection of books to create a new collection of books with a modified title..

Transformer transformer = new Transformer() {
 public Object transform(final Object obj) {
 Book book = (Book) obj;
 return new Book("X " + book.getTitle(), book.getPublished());
 }
 };
 Collection<Book> transformedBooks = CollectionUtils.collect(books,
 transformer);
 CollectionUtils.forAllDo(transformedBooks, closure);
 // the book's title is: X Some book
 // the book's title is: X Another book
 // the book's title is: X I luv codin

Funcito

Funcito is a shiny new library that simplifies access to our favourite functional java libraries like functionaljava, guava or jedi – and allows us to use the structures of these frameworks with less writing ;)

The following libraries and features are currently supported:

  • Google Guava Function and Predicate interfaces
  • Functional Java the F (function) interface
  • Jedi-core Functor and Filter interfaces
  • Play! Framework 2 F.Function interface
  • Collection-generic Transformer and Predicate interfaces

I’ll be covering only a few examples here but if you’re interested, please take a deeper look at the Funcito project website.

Maven Dependencies

One dependency needed .. simply add this one to your pom.xml

<dependency>
    <groupId>com.googlecode.funcito</groupId>
    <artifactId>funcito</artifactId>
    <version>1.2.0</version>
</dependency>

Guava Predicates in short

The first examples shows how to create Guava predicates with a shorter syntax

package com.hascode.tutorial;
 
import static com.google.common.collect.Lists.newArrayList;
import static org.funcito.FuncitoGuava.callsTo;
import static org.funcito.FuncitoGuava.predicateFor;
 
import java.util.List;
 
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
 
public class FuncitoExample1 {
	public static void main(final String[] args) {
		List<User> users = newArrayList(new User("Bob", false), new User("Tim",
				true), new User("Suz", true), new User("Charlize", false),
				new User("Allan", false), new User("Steve", true));
 
		Predicate<User> activeUsers = predicateFor(callsTo(User.class)
				.isActive());
 
		System.out.println("active users are:");
		System.out.println(Iterables.filter(users, activeUsers).toString());
	}
 
	private static class User {
		private final String name;
		private final boolean active;
 
		public User(final String name, final boolean active) {
			this.name = name;
			this.active = active;
		}
 
		public String getName() {
			return name;
		}
 
		public boolean isActive() {
			return active;
		}
 
		@Override
		public String toString() {
			return "User [name=" + name + ", active=" + active + "]";
		}
	}
}

This produces the following output:

active users are:
[User [name=Tim, active=true], User [name=Suz, active=true], User [name=Steve, active=true]]

Guava Functions and Transformers

In the following example we’re defining a function handling the users’ names and use this function to transform the list of users into a list of strings (the users’ names).

package com.hascode.tutorial;
 
import static com.google.common.collect.Lists.newArrayList;
import static org.funcito.Funcito.callsTo;
import static org.funcito.FuncitoGuava.functionFor;
 
import java.util.List;
 
import com.google.common.base.Function;
import com.google.common.collect.Lists;
 
public class FuncitoExample2 {
	public static void main(final String[] args) {
		List<User> users = newArrayList(new User("Bob", false), new User("Tim",
				true), new User("Suz", true), new User("Charlize", false),
				new User("Allan", false), new User("Steve", true));
 
		System.out.println("user names:");
		Function<User, String> namesFunc = functionFor(callsTo(User.class)
				.getName());
		List<String> userNames = Lists.transform(users, namesFunc);
		System.out.println(userNames);
	}
 
	private static class User {
		private final String name;
		private final boolean active;
 
		public User(final String name, final boolean active) {
			this.name = name;
			this.active = active;
		}
 
		public String getName() {
			return name;
		}
 
		public boolean isActive() {
			return active;
		}
 
		@Override
		public String toString() {
			return "User [name=" + name + ", active=" + active + "]";
		}
	}
}

Running the example above should print the following result

user names:
[Bob, Tim, Suz, Charlize, Allan, Steve]

Pure Java

Having shown a lot of libraries here are some examples in pure Java..

In the first example, a Runnable is used as a sort of higher order function ..

new Thread(new Runnable() {
 public void run() {
 System.out.println("i am enclosed ;)");
 }
 }).start();

Another common examples is the Comparator interface that allows to sort collections ..

List<String> names = new ArrayList<String>();
 names.add("Tim");
 names.add("Bart");
 names.add("Zaphod");
 Collections.sort(names, new Comparator<String>() {
 public int compare(final String s1, final String s2) {
 return s2.compareTo(s1);
 }
 });
 // output: [Zaphod, Tim, Bart]
 System.out.println(names.toString());

Other Libraries

There is a bunch of other libraries out there some of them promising some others are not active developed any more ..

Tutorial Sources

I have put the source from this tutorial on my Bitbucket repository – download it there or check it out using Mercurial:

hg clone https://bitbucket.org/hascode/functional-java-examples

Resources

Tags: , , , , , , , , , , , , ,

4 Responses to “Aspects of Functional Programming in Java”

  1. Channing Walton Says:

    We wrote a library called Jedi many years ago (http://jedi.codehaus.org/) that has an interesting feature: annotations to generate functions and eliminate the boiler plate of creating them manually. Here is an example: http://jedi.codehaus.org/Annotations

  2. micha kops Says:

    interesting! thanks for sharing!

  3. Kevin Welker Says:

    I have just released an update to Funcito as version 1.3.0, which adds support for an additional functional API (the Netflix RxJava framework), as well as a cool new feature called “modes — including a Safe Navigation mode (like the Groovy safe navigation operator) to handle nulls while chaining method calls. http://funcito.googlecode.com

  4. micha kops Says:

    Sound interesting, thanks for the update! :)

Search
Categories