Home > OS >  Java call multiple selected methods in a loop
Java call multiple selected methods in a loop

Time:06-09

I'm looking for some help in optimizing my code and write it using less number of lines. I have a Class say A which has few methods defined like below:

Class A{
    public void doSomethingA(){
    }
    public void doSomethingB(){
    }
    public void doSomethingC(){
    }
    public void verifySomethingXYZ(){
    }
    public void verifySomethingLMN(){
    }
}

Now I have a separate class say B and methods written like below

Class B{
    public void test(){
    }

    public void verifyMyMethods(){

    A objA = new A();
    objA.doSomethingA();
    test();
    objA.doSomethingB();
    test();
    objA.doSomethingC();
    test();
    }
}

All of this code runs well. I'm just trying to see if there is a better way I can keep calling those methods like objA.doSomethingA() inside verifyMyMethods() so I can do the same work using less number of code lines.

I would like to call methods doSomethingA(), doSomethingB(), doSomethingC() etc. in a loop. But not sure how it can be done. One approach was to use Java.lang.Class.getMethod(). But this will return all the methods defined in a class.

I did check this [https://stackoverflow.com/questions/12566107/how-to-call-multiple-methods-using-loop-in-java ] exisitng post, but my problem is I just do not want to call all the methods defined inside class A. Only some of them. And since I will be calling some 10-20 methods from Class A in Class B, I would like to do this in slightly better fashion.

There is another solution I saw in Python [https://stackoverflow.com/questions/55458933/how-to-call-multiple-methods-of-a-class-in-a-loop]

name = YourClass()
methods = [name.alex,  name.john, name.claire ] # ...

for m in methods:
    m()

But how can this be done in Java? Here is what I tried. But it gives null pointer exception.

public void try(){
    List<String> l = Lists.newArrayList("objA.doSomethingA","objA.doSomethingB","objA.doSomethingC");
    for (String i : l){
        try{
            Method mett =objA.getClass().getMethod(i); // null pointer exception thrown for this line
            mett.invoke(i);
        } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e){
        }
    }

CodePudding user response:

You must wrap the method invocations in a function to achieve that. Consumer is a good candidate for your case.

Represents an operation that accepts a single input argument and returns no result

An implementation may look like this:

class MethodInvocation implements Consumer<A> {

    @Override
    public void accept(A a) {
      a.doSomethingA();
    }
  }

That's too long to do for every method invocation and since Consumer is a functional interface, we can just use lambdas or method references.

public class Temp {

  public static void main(String[] args) throws Exception {
    A objA = new A();
    List<Consumer<A>> consumers = Arrays.asList(a -> a.doSomethingA(), A::doSomethingB, A::doSomethingC);
    for (Consumer<A> consumer : consumers) {
      consumer.accept(objA);
    }
  }
}

CodePudding user response:

Just another solution:

public class A {
    public void doSomethingA(){
        System.out.println("Calling doSomethingA");
    }
    public void doSomethingB(){
        System.out.println("Calling doSomethingB");
    }
    public void doSomethingC(){
        System.out.println("Calling doSomethingC");
    }
    public void verifySomethingXYZ(){
        System.out.println("Calling verifySomethingXYZ");
    }
    public void verifySomethingLMN(){
        System.out.println("Calling verifySomethingLMN");
    }
}

public class Main {
    public static void main(String[] args) {
        List<String> methodsToCall = new ArrayList<>(Arrays.asList("doSomethingA", "doSomethingB", "doSomethingC"));
        callDesiredMethods(methodsToCall);
    }

    public static void callDesiredMethods(List<String> methodsToCall) {
        Class clazz = A.class;
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            if (methodsToCall.contains(method.getName())) {
                try {
                    method.invoke(clazz.newInstance());
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                } catch (InstantiationException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
  • Related