[ACCEPTED]-What's the nearest substitute for a function pointer in Java?-function-pointers

Accepted answer
Score: 272

Anonymous inner class

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

interface StringFunction {
    int func(String param);
}

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

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

And would be called 2 like so:

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

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

ref.takingMethod(param -> bodyExpression);
Score: 32

For each "function pointer", I'd 6 create a small functor class that implements your calculation. Define 5 an interface that all the classes will implement, and 4 pass instances of those objects into your 3 larger function. This is a combination of 2 the "command pattern", and "strategy pattern".

@sblundy's 1 example is good.

Score: 28

When there is a predefined number of different 6 calculations you can do in that one line, using 5 an enum is a quick, yet clear way to implement 4 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 3 method declaration, as well as exactly one 2 instance of each implementation are all 1 defined in a single class/file.

Score: 24

You need to create an interface that provides 13 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 12 you need to pass a function, you can implement 11 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 10 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 9 can often use Runnable instead of your own 8 interface if you don't need to pass in parameters, or 7 you can use various other techniques to 6 make the param count less "fixed" but it's 5 usually a trade-off with type safety. (Or 4 you can override the constructor for your 3 function object to pass in the params that 2 way.. there are lots of approaches, and 1 some work better in certain circumstances.)

Score: 18

Method references using the :: operator

You can use method references in method 12 arguments where the method accepts a functional interface. A 11 functional interface is any interface that 10 contains only one abstract method. (A functional 9 interface may contain one or more default 8 methods or static methods.)

IntBinaryOperator is a functional 7 interface. Its abstract method, applyAsInt, accepts 6 two ints as its parameters and returns an int. Math.max also 5 accepts two ints and returns an int. In this example, A.method(Math::max); makes 4 parameter.applyAsInt send its two input values to Math.max and return 3 the result of that Math.max.

import java.util.function.IntBinaryOperator;

class A {
    static void method(IntBinaryOperator parameter) {
        int i = parameter.applyAsInt(7315, 89163);
        System.out.println(i);
    }
}
import java.lang.Math;

class B {
    public static void main(String[] args) {
        A.method(Math::max);
    }
}

In general, you can 2 use:

method1(Class1::method2);

instead of:

method1((arg1, arg2) -> Class1.method2(arg1, arg2));

which is short for:

method1(new Interface1() {
    int method1(int arg1, int arg2) {
        return Class1.method2(arg1, agr2);
    }
});

For more 1 information, see :: (double colon) operator in Java 8 and Java Language Specification §15.13.

Score: 15

You can also do this (which in some RARE occasions 11 makes sense). The issue (and it is a big 10 issue) is that you lose all the typesafety 9 of using a class/interface and you have 8 to deal with the case where the method does 7 not exist.

It does have the "benefit" that 6 you can ignore access restrictions and call 5 private methods (not shown in the example, but 4 you can call methods that the compiler would 3 normally not let you call).

Again, it is 2 a rare case that this makes sense, but on 1 those occasions it is a nice tool to have.

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

class Main
{
    public static void main(final String[] argv)
        throws NoSuchMethodException,
               IllegalAccessException,
               IllegalArgumentException,
               InvocationTargetException
    {
        final String methodName;
        final Method method;
        final Main   main;

        main = new Main();

        if(argv.length == 0)
        {
            methodName = "foo";
        }
        else
        {
            methodName = "bar";
        }

        method = Main.class.getDeclaredMethod(methodName, int.class);

        main.car(method, 42);
    }

    private void foo(final int x)
    {
        System.out.println("foo: " + x);
    }

    private void bar(final int x)
    {
        System.out.println("bar: " + x);
    }

    private void car(final Method method,
                     final int    val)
        throws IllegalAccessException,
               IllegalArgumentException,
               InvocationTargetException
    {
        method.invoke(this, val);
    }
}
Score: 13

If you have just one line which is different 3 you could add a parameter such as a flag 2 and a if(flag) statement which calls one 1 line or the other.

Score: 12
Score: 11

New Java 8 Functional Interfaces and Method References using the :: operator.

Java 8 is able to maintain method references 15 ( MyClass::new ) with "@ Functional Interface" pointers. There 14 are no need for same method name, only same 13 method signature required.

Example:

@FunctionalInterface
interface CallbackHandler{
    public void onClick();
}

public class MyClass{
    public void doClick1(){System.out.println("doClick1");;}
    public void doClick2(){System.out.println("doClick2");}
    public CallbackHandler mClickListener = this::doClick;

    public static void main(String[] args) {
        MyClass myObjectInstance = new MyClass();
        CallbackHandler pointer = myObjectInstance::doClick1;
        Runnable pointer2 = myObjectInstance::doClick2;
        pointer.onClick();
        pointer2.run();
    }
}

So, what 12 we have here?

  1. Functional Interface - this is interface, annotated or not with @FunctionalInterface, which contains only one method declaration.
  2. Method References - this is just special syntax, looks like this, objectInstance::methodName, nothing more nothing less.
  3. Usage example - just an assignment operator and then interface method call.

YOU SHOULD USE FUNCTIONAL INTERFACES 11 FOR LISTENERS ONLY AND ONLY FOR THAT!

Because 10 all other such function pointers are really 9 bad for code readability and for ability 8 to understand. However, direct method references 7 sometimes come handy, with foreach for example.

There 6 are several predefined Functional Interfaces:

Runnable              -> void run( );
Supplier<T>           -> T get( );
Consumer<T>           -> void accept(T);
Predicate<T>          -> boolean test(T);
UnaryOperator<T>      -> T apply(T);
BinaryOperator<T,U,R> -> R apply(T, U);
Function<T,R>         -> R apply(T);
BiFunction<T,U,R>     -> R apply(T, U);
//... and some more of it ...
Callable<V>           -> V call() throws Exception;
Readable              -> int read(CharBuffer) throws IOException;
AutoCloseable         -> void close() throws Exception;
Iterable<T>           -> Iterator<T> iterator();
Comparable<T>         -> int compareTo(T);
Comparator<T>         -> int compare(T,T);

For 5 earlier Java versions you should try Guava 4 Libraries, which has similar functionality, and 3 syntax, as Adrian Petrescu has mentioned 2 above.

For additional research look at Java 8 Cheatsheet

and 1 thanks to The Guy with The Hat for the Java Language Specification §15.13 link.

Score: 9

@sblundy's answer is great, but anonymous 27 inner classes have two small flaws, the 26 primary being that they tend not to be reusable 25 and the secondary is a bulky syntax.

The 24 nice thing is that his pattern expands into 23 full classes without any change in the main 22 class (the one performing the calculations).

When 21 you instantiate a new class you can pass 20 parameters into that class which can act 19 as constants in your equation--so if one 18 of your inner classes look like this:

f(x,y)=x*y

but 17 sometimes you need one that is:

f(x,y)=x*y*2

and maybe 16 a third that is:

f(x,y)=x*y/2

rather than making two anonymous 15 inner classes or adding a "passthrough" parameter, you 14 can make a single ACTUAL class that you 13 instantiate as:

InnerFunc f=new InnerFunc(1.0);// for the first
calculateUsing(f);
f=new InnerFunc(2.0);// for the second
calculateUsing(f);
f=new InnerFunc(0.5);// for the third
calculateUsing(f);

It would simply store the 12 constant in the class and use it in the 11 method specified in the interface.

In fact, if 10 KNOW that your function won't be stored/reused, you 9 could do this:

InnerFunc f=new InnerFunc(1.0);// for the first
calculateUsing(f);
f.setConstant(2.0);
calculateUsing(f);
f.setConstant(0.5);
calculateUsing(f);

But immutable classes are 8 safer--I can't come up with a justification 7 to make a class like this mutable.

I really 6 only post this because I cringe whenever 5 I hear anonymous inner class--I've seen 4 a lot of redundant code that was "Required" because 3 the first thing the programmer did was go 2 anonymous when he should have used an actual 1 class and never rethought his decision.

Score: 6

The Google Guava libraries, which are becoming very popular, have 2 a generic Function and Predicate object that they have worked 1 into many parts of their API.

Score: 5

One of the things I really miss when programming 22 in Java is function callbacks. One situation 21 where the need for these kept presenting 20 itself was in recursively processing hierarchies 19 where you want to perform some specific 18 action for each item. Like walking a directory 17 tree, or processing a data structure. The 16 minimalist inside me hates having to define 15 an interface and then an implementation 14 for each specific case.

One day I found myself 13 wondering why not? We have method pointers 12 - the Method object. With optimizing JIT 11 compilers, reflective invocation really 10 doesn't carry a huge performance penalty 9 anymore. And besides next to, say, copying 8 a file from one location to another, the 7 cost of the reflected method invocation 6 pales into insignificance.

As I thought more 5 about it, I realized that a callback in 4 the OOP paradigm requires binding an object 3 and a method together - enter the Callback 2 object.

Check out my reflection based solution 1 for Callbacks in Java. Free for any use.

Score: 4

Sounds like a strategy pattern to me. Check 1 out fluffycat.com Java patterns.

Score: 4

To do the same thing without interfaces 1 for an array of functions:

class NameFuncPair
{
    public String name;                // name each func
    void   f(String x) {}              // stub gets overridden
    public NameFuncPair(String myName) { this.name = myName; }
}

public class ArrayOfFunctions
{
    public static void main(String[] args)
    {
        final A a = new A();
        final B b = new B();

        NameFuncPair[] fArray = new NameFuncPair[]
        {
            new NameFuncPair("A") { @Override void f(String x) { a.g(x); } },
            new NameFuncPair("B") { @Override void f(String x) { b.h(x); } },
        };

        // Go through the whole func list and run the func named "B"
        for (NameFuncPair fInstance : fArray)
        {
            if (fInstance.name.equals("B"))
            {
                fInstance.f(fInstance.name + "(some args)");
            }
        }
    }
}

class A { void g(String args) { System.out.println(args); } }
class B { void h(String args) { System.out.println(args); } }
Score: 4

oK, this thread is already old enough, so 17 very probably my answer is not helpful for the question. But 16 since this thread helped me to find my solution, I'll 15 put it out here anyway.

I needed to use a 14 variable static method with known input 13 and known output (both double). So then, knowing 12 the method package and name, I could work 11 as follows:

java.lang.reflect.Method Function = Class.forName(String classPath).getMethod(String method, Class[] params);

for a function that accepts one 10 double as a parameter.

So, in my concrete 9 situation I initialized it with

java.lang.reflect.Method Function = Class.forName("be.qan.NN.ActivationFunctions").getMethod("sigmoid", double.class);

and invoked 8 it later in a more complex situation with

return (java.lang.Double)this.Function.invoke(null, args);

java.lang.Object[] args = new java.lang.Object[] {activity};
someOtherFunction() + 234 + (java.lang.Double)Function.invoke(null, args);

where 7 activity is an arbitrary double value. I 6 am thinking of maybe doing this a bit more 5 abstract and generalizing it, as SoftwareMonkey 4 has done, but currently I am happy enough 3 with the way it is. Three lines of code, no 2 classes and interfaces necessary, that's 1 not too bad.

Score: 3

Check out lambdaj

http://code.google.com/p/lambdaj/

and in particular its 4 new closure feature

http://code.google.com/p/lambdaj/wiki/Closures

and you will find a very 3 readable way to define closure or function 2 pointer without creating meaningless interface 1 or use ugly inner classes

Score: 3

Wow, why not just create a Delegate class 16 which is not all that hard given that I 15 already did for java and use it to pass 14 in parameter where T is return type. I am 13 sorry but as a C++/C# programmer in general 12 just learning java, I need function pointers 11 because they are very handy. If you are 10 familiar with any class which deals with 9 Method Information you can do it. In java 8 libraries that would be java.lang.reflect.method.

If 7 you always use an interface, you always 6 have to implement it. In eventhandling there 5 really isn't a better way around registering/unregistering 4 from the list of handlers but for delegates 3 where you need to pass in functions and 2 not the value type, making a delegate class 1 to handle it for outclasses an interface.

Score: 3

None of the Java 8 answers have given a 4 full, cohesive example, so here it comes.

Declare 3 the method that accepts the "function pointer" as 2 follows:

void doCalculation(Function<Integer, String> calculation, int parameter) {
    final String result = calculation.apply(parameter);
}

Call it by providing the function 1 with a lambda expression:

doCalculation((i) -> i.toString(), 2);
Score: 1

If anyone is struggling to pass a function 3 that takes one set of parameters to define 2 its behavior but another set of parameters 1 on which to execute, like Scheme's:

(define (function scalar1 scalar2)
  (lambda (x) (* x scalar1 scalar2)))

see Pass Function with Parameter-Defined Behavior in Java

Score: 1

Since Java8, you can use lambdas, which 6 also have libraries in the official SE 8 5 API.

Usage: You need to use a interface with only 4 one abstract method. Make an instance of 3 it (you may want to use the one java SE 2 8 already provided) like this:

Function<InputType, OutputType> functionname = (inputvariablename) {
... 
return outputinstance;
}

For more information 1 checkout the documentation: https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html

Score: 1

Prior to Java 8, nearest substitute for 6 function-pointer-like functionality was 5 an anonymous class. For example:

Collections.sort(list, new Comparator<CustomClass>(){
    public int compare(CustomClass a, CustomClass b)
    {
        // Logic to compare objects of class CustomClass which returns int as per contract.
    }
});

But now 4 in Java 8 we have a very neat alternative 3 known as lambda expression, which can be used as:

list.sort((a, b) ->  { a.isBiggerThan(b) } );

where isBiggerThan 2 is a method in CustomClass. We can also use method 1 references here:

list.sort(MyClass::isBiggerThan);
Score: 0

The open source safety-mirror project generalizes some 12 of the above mentioned solutions into a 11 library that adds functions, delegates and 10 events to Java.

See the README, or this stackoverflow answer, for 9 a cheat sheet of features.

As for functions, the 8 library introduces a Fun interface, and 7 some sub-interfaces that (together with 6 generics) make up a fluent API for using 5 methods as types.

Fun.With0Params<String> myFunctionField = "   hello world   "::trim;`  
Fun.With2Params<Boolean, Object, Object> equals = Objects::equals;`  
    
public void foo(Fun.With1ParamAndVoid<String> printer) throws Exception {
    printer.invoke("hello world);
}  

public void test(){
    foo(System.out::println);
}  

Notice:

  1. that you must choose the sub-interface that matches the number of parameters in the signature you are targeting. Fx, if it has one parameter, choose Fun.With1Param.
  2. that Generics are used to define A) the return type and B) the parameters of the signature.

Also, notice that 4 the signature of the Method Reference passed 3 to the call to the foo() method must match 2 the the Fun defined by method Foo. If it 1 do not, the compiler will emit an error.

More Related questions