user3471312
user3471312

Reputation: 11

How can I write code that uses a different method for different parameters without using "if-else if"?

To me, if-else if is too long and hard to read.

Is there some table-driven approach I can use to map an input value to call a specific method for that value?

For example:

for(String id:ids){

    Test test = new Test();

    if(id == "101") {    
        test.method1();
    }else if(id=="102") {
        test.method2();
    }else if(id=="103"){
        test.method3();
     ...

Upvotes: 1

Views: 101

Answers (3)

Don Roby
Don Roby

Reputation: 41137

As it is, your code is not quite correct, as it's using == to check equality of strings.

You should use the equals method:

for(String id: ids){

    Test test = new Test();

    if(id.equals("101")) {
        test.method1();
    }else if(id.equals("102")) {
        test.method2();
    }else if(id.equals("102")){
        test.method3();
    // etc.
    }
}

Other answers have suggested a creating a method map Map<String,Method> and using reflection. This will work and may be perfectly reasonable for your use, but loses some compile-time type safety checks.

You can get those checks back by defining an interface and populating a map with instances of that interface:

interface TestMethod {
   void  execute(Test test);
}

private static HashMap<String, TestMethod> methodMap = new HashMap<String, TestMethod>();

static {
    methodMap.put("101", new TestMethod(){
        @Override
        public void execute(Test test) {
            test.method1();
        }
    });
    methodMap.put("102", new TestMethod(){
        @Override
        public void execute(Test test) {
            test.method2();
        }
    });
    methodMap.put("103", new TestMethod() {
        @Override
        public void execute(Test test) {
            test.method3();
        }
    });
    // etc.
}

and then your loop can be coded as

for (String id: ids) {
    Test test = new Test();
    methodMap.get(id).execute(test);
}

As it is here, this unfortunately makes the code longer and leaves it at least as difficult to read. But if you're using Java 8, you can use lambda expressions to populate the map, which would make the static initializer block look more like:

static {
    methodMap.put("101", t -> t.method1();
    methodMap.put("102", t -> t.method2();
    methodMap.put("103", t -> t.method3();
    // etc.
}

and then it might actually be worth doing.

However, if this sort of conditional based on some kind of string "code" is common in your application, and especially if you have multiple conditionals depending on the same codes, you might want a much broader redesign to encapsulate the different actions done for the different codes in a class hierarchy and use polymorphism instead of either if-else (or switch) or a method map lookup. You're still likely to need some conditionals to build the instances of your classes, but the code might be greatly improved.

Upvotes: 1

EdwinW
EdwinW

Reputation: 1036

...
static Map<String,Method> methods = new HashMap<String,Method>();
...
static {
    methods.put("101",Test.class.getMethod("method1",null));
    methods.put("102",Test.class.getMethod("method2",null));
    ...
}
...
for( String id : ids ) {
    Test test = new Test();
    Method m = methods.get(id);
    if (m != null) {
        m.invoke(test,null);
    }
}

Of course, all this really does is trade the pain of the if/else chain for the pain of initializing the hash with all the methods.

Upvotes: 2

Ishtiaq
Ishtiaq

Reputation: 1058

You can use reflection to call method. Construct the method name from the string and Use Method Class from java.lang.reflect namespace to invoke the method and pass parameters. Something like this

Method theMethod = yourClass.getClass().getMethod("methodName", null);
method.invoke(yourClass, );

Upvotes: 1

Related Questions