Tuesday, June 10, 2008

A simple Java FP list map

Following on the comments I received on my previous entry about doing a bit of Java functional programming style, I made a very simple class to map a list. I'm following the style of what I have seen in the apache collections utilities. See previous post.

First note that I am doing it without generics (I'm stuck with jdk1.4.2 at work), so for some this would be old style Java programming.

Here's the utility class.
ListUtils.java

package fp;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class ListUtils {
static public List map(List elements, Applier applier) {
List result = new ArrayList();
for (Iterator it = elements.iterator(); it.hasNext();) {
Object element = it.next();
result.add(applier.apply(element));
}
return result;
}
}


And the interface used by the utility class.
Applier.java

package fp;

public interface Applier {
public Object apply(Object element);
}


Here's a client code example.

WithPoints.java

package domino;

public interface WithPoints {
public Integer getPoints();
}


Domino.java

package domino;

public class Domino implements WithPoints {
private Integer points;

public Domino(int points) {
this.points = new Integer(points);
}

public Integer getPoints() {
return points;
}
}


And finally!

package domino;

import fp.Applier;
import fp.ListUtils;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Main {

public static void main(String[] args) {
List dominoes = new ArrayList();
dominoes.add(new Domino(1));
dominoes.add(new Domino(2));
dominoes.add(new Domino(3));

List points = ListUtils.map(dominoes, new Applier() {
public Object apply(Object domino) {
return ((WithPoints) domino).getPoints();
}
});

System.out.println(points); // [1, 2, 3]
}
}


So this time around, I did get a new list instead of transforming a list but I still think the simple iterator style is clearer and it avoids using a "utility class" for doing something really simple.

Iterator style

List points;
for (Iterator iter = Dominoes.iterator(); iter.hasNext();) {
points.add((WithPoints) iter.next().getPoints());
}


And of course, Scala still is neater for me 8)

val points = dominoes map (x => x.points)

3 comments:

Steven said...

http://code.google.com/p/google-collections/

has Function and Predicate interfaces and static functions to transform Iterables and Iterators.

It's not as brief as Scala, but workable...

Channing Walton said...

Hi, you might be interested in Jedi... "Jedi provides a library of routines inspired by more powerful languages such as Lisp, which support first order logic, filtering, iteration, type conversion of collections, etc. It makes extensive use of higher order functions and closures (also known as ‘blocks’ or ‘lambdas’), but the key is that you do not have to write them yourself."

Channing Walton said...

ps. Here are some examples of Jedi: http://jedi.codehaus.org/Examples