2

Please give me an advice and example how I can implement this situation when I should call different methods up to incoming params with Map.

public String mainMethod(Int count) {
    if (count == 1) { return myMethod }
    else if (count == 2) { return myMethod2 }
    else if (count == 3) { return myMethod3 }
}

public String myMethod1() {
    ..............  
} 

public String myMethod2() {
    ..............  
} 

public String myMethod3() {
    ..............  
} 
Vlad Schnakovszki
  • 8,434
  • 6
  • 80
  • 114
zhake
  • 29
  • 1
  • 5
  • what's wrong with `return myMethod()`, that will work. I'd recommend better spacing for readability. I'm not exactly sure what you're asking, where does a Map come into play? – turbo Feb 18 '14 at 14:16
  • you're on the right way. If you don't want to have a lot of if conditions have a look at "switch-case" – Danny. Feb 18 '14 at 14:17
  • Is lack of `()` in `method` invocation just typo? – Pshemo Feb 18 '14 at 14:18
  • 3
    Please explain more clearly what you mean by "solution with Map", it is not obvious. – turbo Feb 18 '14 at 14:19
  • If you mean you want a `Map` from `Integer` to method invocation, you are going to find it a little convoluted in java... Is this what you mean? – Marco Bolis Feb 18 '14 at 14:24
  • over here (http://stackoverflow.com/questions/13398885/call-different-methods-by-its-parameter?rq=1) I found some information that this would be easier to implement Map.. But I am not shure how to do this – zhake Feb 18 '14 at 14:26

6 Answers6

3

What was mentioned in question you pointed out in your comment was something like this:

Map<Integer, Callable> map = new HashMap<>();
map.put(1, new Callable() {
    public Object call() throws Exception {
        //code for argument 1
        return null;
    }
});
map.put(2, new Callable() {
    public Object call() throws Exception {
        //code for argument 2
        return null;
    }
});
map.put(3, new Callable() {
    public Object call() throws Exception {
        //code for argument 3
        return null;
    }
});

Now you can use it as

map.get(count).call();
Pshemo
  • 122,468
  • 25
  • 185
  • 269
1

You should use an enum with descriptive names of the different method calls, and make the myMethod's private. For example, something like:

public enum Method { GOOD, BAD, UGLY; }

public String mainMethod(Method method) {
    switch (method) {
    case GOOD: return myMethod1();
    case BAD:  return myMethod2();
    case UGLY: return myMethod3();
    }
}

private String myMethod1() { ... };
private String myMethod2() { ... };
private String myMethod3() { ... };
mbroshi
  • 969
  • 8
  • 21
  • you need break statements in your switch and this doesn't really answer the question – turbo Feb 18 '14 at 14:36
  • If you have return statements in the switch statement, you don't need breaks. Anyway, I agree, that this doesn't really answer OPs (very badly asked) question. – bobbel Feb 18 '14 at 14:51
0

You need a static Map<Integer, Callable> filled with anonymous classes for every possible integer input and then return MAP.get(count).call();.

Smutje
  • 17,733
  • 4
  • 24
  • 41
0
public abstract class MethodImplementation
{
    private static final Map<Integer, SomeInterface>    IMPLEMENTATION_MAP;

    static
    {
        IMPLEMENTATION_MAP  = new HashMap<>();

        IMPLEMENTATION_MAP.put( 1, new Implementation1() );
        IMPLEMENTATION_MAP.put( 2, new Implementation2() );
        IMPLEMENTATION_MAP.put( 3, new Implementation3() );

    }

    public static interface SomeInterface
    {
        public String Method();

    }

    public static String Selector( int count_ )
    {
        String          result          = null;
        SomeInterface   implementation  = IMPLEMENTATION_MAP.get( count_ );

        if( null != implementation )
        {
            result  = implementation.Method();

        }

        return result;

    }

    public static class Implementation1 implements SomeInterface
    {
        @Override
        public String Method()
        {
            String  result  = "Method1";

            return result;

        }

    }

    public static class Implementation2 implements SomeInterface
    {
        @Override
        public String Method()
        {
            String  result  = "Method2";

            return result;

        }

    }

    public static class Implementation3 implements SomeInterface
    {
        @Override
        public String Method()
        {
            String  result  = "Method3";

            return result;

        }

    }

    private MethodImplementation()
    {

    }

}

usage:

String  res = MethodImplementation.Selector( i );
Maxim
  • 339
  • 1
  • 5
0

You can also use reflection for the same.

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

public class InvokeMethod {

    /**
     * Map of input integer to method name to be invoked.
     */
    private final static Map<Integer, String> methods = new HashMap<>();
    static {
        methods.put(1, "method1");
        methods.put(2, "method2");
        methods.put(3, "method3");
    }

    /**
     * @param count Method identifier.
     */
    public static void mainMethod(int count) {
        String methodName = methods.get(count);
        Method method = null;

        try {
            // Check the javadoc of the following method to see how to
            // handle multiple arguments
            method = InvokeMethod.class.getDeclaredMethod(methodName, int.class);
        } catch (NoSuchMethodException e) {
            System.out.println("ERROR: Method not found: " + methodName);
            System.exit(1);
        } catch (SecurityException e) {
            System.out.println("ERROR: Unable to access the method: " + methodName);
            System.exit(1);
        }

        try {
            // Invoking statically, so passing null.
            // Else the class instance needs to be passed.
            // Go through the javadoc of the following method to see
            // how to handle multiple arguments.
            method.invoke(null, 5);
        } catch (InvocationTargetException | IllegalAccessException e) {
            System.out.println("ERROR: Unable to access the method: " + methodName);
            System.exit(1);
        } catch (IllegalArgumentException e) {
            System.out.println("ERROR: Incorrect arguments passed: " + methodName);
            System.exit(1);
        }
    }

    /**
     * Prints the number as is.
     * @param in Input integer.
     */
    public static void method1(int in) {
        System.out.println(in);
    }

    /**
     * Doubles the number and prints it.
     * @param in Input integer.
     */
    public static void method2(int in) {
        System.out.println(in * 2);
    }

    /**
     * Squares the number and prints it.
     * @param in Input integer.
     */
    public static void method3(int in) {
        System.out.println(in * in);
    }
}
sid
  • 83
  • 8
0

The solution with adding callables to a map looks good, but now with Java 8 it can be simplified like so:

Map<Integer, Callable> map = new HashMap<>();
map.put(1, () -> null);
map.put(2, () -> 33);
map.put(3, () -> 66);

or if you want to use other methods defined in the class:

Map<Integer, Callable> map = new HashMap<>();
map.put(1, ClassName::myMethod1);
map.put(2, ClassName::myMethod2);
map.put(3, ClassName::myMethod3);

And then call the method same as in the previous solution: map.get(count).call();

OlgaMaciaszek
  • 3,662
  • 1
  • 28
  • 32