How does one do function pointers in Java ?
You can't, but lets see if we can work around this.
First lets address the question "Why bother?" Having explored such languages as Ruby and Groovy I've grown fond of closures. Things like callback functions are awkward in Java because you always have to implement an interface a particular object expects. Consider Swing event listeners as a case in point. Wouldn't it be nice to just pass a simple function into a button that will be called each time a button is clicked ? Of course it would be, a lot of things would be simpler.
So I thought about it for a few minutes and came up with the following example. In Java you can't have function pointers. Callback functions are really objects that implement a particular interface. So here is what a closure interface would look like:
public interface Closure {
public Object yield(Object... objects);
}
"Closure" is a simple interface that declares a function that takes any number of some arguments, whatever type they might be, and returns a value, whatever type that might be.
Here is an example of a collection class that uses closures for traversing or inspecting the data structure:
import java.util.*;
public class ArrayListPlus extends ArrayList {
public void each(Closure cl)
{
for (Object o : this)
{
cl.yield(o);
}
}
public ArrayListPlus findAll(final Closure c) {
final ArrayListPlus result=new ArrayListPlus();
each(new Closure() {
public Object yield(Object... objects) {
if ((Boolean) (c.yield(objects[0])))
{
result.add(objects[0]);
}
return null;
}
});
return result;
}
public static void main(String args[])
{
ArrayListPlus foo=new ArrayListPlus();
for (int i=0;i<10;i++)
{
foo.add(Math.random()*100.0);
}
System.out.println("Trying each");
foo.each(new Closure() {
public Object yield(Object... objects) {
System.out.println(objects[0]);
return null;
}
});
System.out.println("Trying find");
System.out.println(foo.findAll(new Closure() {
public Object yield(Object... objects) {
return (Double) objects[0] < 50.0;
}
}));
}
}
There is no rocket science to this. I think this is the best I could do given the limitations of Java, but it was nevertheless a good exercise.