-2

I am looking for analogous implementation of the following in Java. This code in C++ is to call methods appropriately using function pointers, depending upon the input, avoiding the ugly if..else ladder. (Please except solution based on Polymorphism - basically creating new classes along with an interface that allows specific implementations. Also cannot use Java 8 (lambda) in my project).

Any alternative in Java?

#include "stdafx.h"
#include <map>
#include <iostream>
using namespace std;

class Func;
typedef void (Func::*FUNC_TYPE) ();

class Func
{
 public:
    Func() 
    {
        fncMap[1] = &Func::fn1;
        fncMap[2] = &Func::fn2;
        fncMap[3] = &Func::fn3;
        fncMap[4] = &Func::fn4;
    }
    void fn1(){ cout << "fn1" << endl; }
    void fn2(){ cout << "fn2" << endl; }
    void fn3(){ cout << "fn3" << endl; }
    void fn4(){ cout << "fn4" << endl; }
    map<int, FUNC_TYPE> fncMap;
};

void callAppropriateFunction (Func& Ob, int input)
{
    auto itrFind = Ob.fncMap.find(input);

    if (itrFind == Ob.fncMap.end()) return;

    FUNC_TYPE fn = itrFind->second;

    (Ob.*fn) ();
}

int _tmain(int argc, _TCHAR* argv[])
{
    Func Ob;
    int i;
    cin >> i;

    callAppropriateFunction(Ob, i);

    return 0;
}
object
  • 796
  • 1
  • 12
  • 21
  • 2
    [What's the nearest substitute for a function pointer in Java?](http://stackoverflow.com/questions/122407/whats-the-nearest-substitute-for-a-function-pointer-in-java) – Bo Persson Oct 22 '15 at 07:16
  • @BoPersson thanks but I can't use Java 8 in my Project. – object Oct 22 '15 at 07:19

3 Answers3

3

Define an interface with one method, or use an existing interface. Then make the list function pointers a list of variables of the interface type.

In your case, you have functions that don't take any parameters and have a void return type. The Java interface Runnable corresponds to that. Use Java 8 method references to refer to the functions.

Here's a Java version of your code.

import java.util.HashMap;
import java.util.Map;

public class Func {

    private final Map<Integer, Runnable> fncMap = new HashMap<>();

    public Func() {
        fncMap.put(1, this::fn1);
        fncMap.put(2, this::fn2);
        fncMap.put(3, this::fn3);
        fncMap.put(4, this::fn4);
    }

    private void fn1() {
        System.out.println("fn1");
    }

    private void fn2() {
        System.out.println("fn2");
    }

    private void fn3() {
        System.out.println("fn3");
    }

    private void fn4() {
        System.out.println("fn4");
    }

    public static void callAppropriateFunction(Func ob, int input) {
        final Runnable fn = ob.fncMap.get(input);
        if (fn != null) {
            fn.run();
        }
    }
}

edit If you can't use Java 8, you can do this in a more elaborate way, using anonymous inner classes instead of method references:

public Func() {
    fncMap.put(1, new Runnable() {
        @Override
        public void run() {
            fn1();
        }
    });

    fncMap.put(2, new Runnable() {
        @Override
        public void run() {
            fn2();
        }
    });

    // etc.
}
Jesper
  • 202,709
  • 46
  • 318
  • 350
1

Try invoke methods via reflecion maybe something like this:

        Method method = YourClass.class.getMethod("fn1", YourClass.class);
        method.invoke();
kkhipis
  • 159
  • 7
0

You can pretty much achieve this using java lambdas (Java 8 and above only)

//declare a functional interface
@java.lang.FunctionalInterface
public interface FunI {
    public void fun();
}

public class MainProgram {

    public static void main(String[] args){
        AnArrayList integers = new AnArrayList();

        //Interface type holds the lambda
        FunI[] functionsArray = [];
        functionsArray.push(()->{System.out.println("1");})
        functionsArray.push(()->{System.out.println("2");})

        //on some criteria
        if(condition){FunI[i].fun();}
    }

}
prasun
  • 7,073
  • 9
  • 41
  • 59