What's the nearest substitute for a function pointer in Java? – Dev

The best answers to the question “What's the nearest substitute for a function pointer in Java?” in the category Dev.

QUESTION:

I have a method that’s about ten lines of code. I want to create more methods that do exactly the same thing, except for a small calculation that’s going to change one line of code. This is a perfect application for passing in a function pointer to replace that one line, but Java doesn’t have function pointers. What’s my best alternative?

ANSWER:

For each “function pointer”, I’d create a small functor class that implements your calculation.
Define an interface that all the classes will implement, and pass instances of those objects into your larger function. This is a combination of the “command pattern”, and “strategy pattern”.

@sblundy’s example is good.

ANSWER:

Anonymous inner class

Say you want to have a function passed in with a String param that returns an int.
First you have to define an interface with the function as its only member, if you can’t reuse an existing one.

interface StringFunction {
    int func(String param);
}

A method that takes the pointer would just accept StringFunction instance like so:

public void takingMethod(StringFunction sf) {
   int i = sf.func("my string");
   // do whatever ...
}

And would be called like so:

ref.takingMethod(new StringFunction() {
    public int func(String param) {
        // body
    }
});

EDIT: In Java 8, you could call it with a lambda expression:

ref.takingMethod(param -> bodyExpression);

ANSWER:

You need to create an interface that provides the function(s) that you want to pass around. eg:

/**
 * A simple interface to wrap up a function of one argument.
 * 
 * @author rcreswick
 *
 */
public interface Function1<S, T> {

   /**
    * Evaluates this function on it's arguments.
    * 
    * @param a The first argument.
    * @return The result.
    */
   public S eval(T a);

}

Then, when you need to pass a function, you can implement that interface:

List<Integer> result = CollectionUtilities.map(list,
        new Function1<Integer, Integer>() {
           @Override
           public Integer eval(Integer a) {
              return a * a;
           }
        });

Finally, the map function uses the passed in Function1 as follows:

   public static <K,R,S,T> Map<K, R> zipWith(Function2<R,S,T> fn, 
         Map<K, S> m1, Map<K, T> m2, Map<K, R> results){
      Set<K> keySet = new HashSet<K>();
      keySet.addAll(m1.keySet());
      keySet.addAll(m2.keySet());

      results.clear();

      for (K key : keySet) {
         results.put(key, fn.eval(m1.get(key), m2.get(key)));
      }
      return results;
   }

You can often use Runnable instead of your own interface if you don’t need to pass in parameters, or you can use various other techniques to make the param count less “fixed” but it’s usually a trade-off with type safety. (Or you can override the constructor for your function object to pass in the params that way.. there are lots of approaches, and some work better in certain circumstances.)

ANSWER:

When there is a predefined number of different calculations you can do in that one line, using an enum is a quick, yet clear way to implement a strategy pattern.

public enum Operation {
    PLUS {
        public double calc(double a, double b) {
            return a + b;
        }
    },
    TIMES {
        public double calc(double a, double b) {
            return a * b;
        }
    }
     ...

     public abstract double calc(double a, double b);
}

Obviously, the strategy method declaration, as well as exactly one instance of each implementation are all defined in a single class/file.