views:

56

answers:

3

Is there a way to convert an array to a list of parameters..?

main(){
   //"a" is an array or a list or some collection
   myPrint(a.SomeMethod);
}

void myPrint(int a){
//Do Stuff to arguments
}

void myPrint(int a, int b){
//Do Stuff to arguments
}

void myPrint(int a, int b, int c){
//Do Stuff to arguments
}

I want to convert "a" into a parameter/argument list so it will automatically call the appropriate function.

+1  A: 
main(){
   int[] a = {1,2,3};
   MyPrint(a);
}

void MyPrint(int... x){
//Do Stuff to arguments (accessing them by its index)
}
Cristian
lets say MyPrint is an overloaded function. I want to be able convert my array into parameters, so i can call a specific overloaded method
Ying Chan
dont't get it... could you explain a little bit more?
Cristian
modified my question above
Ying Chan
Is MyPrint always going to be calling with x number of ints? If so, this solution will work. But if they are all going to be different types, then I would say your best solution is to do it manually. But I guess I'm still a little confused about what you are trying to do. Is your array a list of arguments into the main method?
shoebox639
A: 

In short, this really isn't possible. The only way to take variable number of arguments is with the int...x construct. Otherwise, you have to figure out how many elements are in a and then figure out which one to call.

if (a.length == 2) {
    MyPrint(a[0], a[1]);
}
else if (a.length == 3) {
    MyPrint(a[0], a[1], a[2]);
}
// etc
shoebox639
+1  A: 

It would be extremely odd to do what you are trying to do. If you are looking for a general purpose way of doing it you would need to dig into reflection (java.lang.reflect). If you really have an array/collection with 1, 2, or 3 ints and want to call a different method based on that then just write a method that figures out the number of values in the "thing" and calls the appropriate method.

Can you tell us why you want to do this?

Edit:

Code for the hard coded way:

public class Main
{
    public static void main(String[] args)
    {
        final Main main;

        main = new Main();
        main.callFoo(new int[] {1});
        main.callFoo(new int[] {1, 2});
        main.callFoo(new int[] {1, 2, 3});
    }

    private void callFoo(final int[] values)
    {
        if(values.length == 1)
        {
            foo(values[0]);
        }
        else if(values.length == 2)
        {
            foo(values[0], values[1]);
        }
        else if(values.length == 3)
        {
            foo(values[0], values[1], values[2]);
        }
        else
        {
            throw new Error("too many values: " + values.length);
        }
    }

    private void foo(int a)
    {
        System.out.println("foo(" + a + ")");
    }

    private void foo(int a, int b)
    {
        System.out.println("foo(" + a + ", " + b + ")");
    }

    private void foo(int a, int b, int c)
    {
        System.out.println("foo(" + a + ", " + b + ", " + c + ")");
    }
}

Here is the reflection version (I would not handle the errors via printStackTrace, but it is a starting point):

public class Main
{
    public static void main(String[] args)
    {
        final Main main;

        main = new Main();
        main.callFoo(new int[] {1});
        main.callFoo(new int[] {1, 2});
        main.callFoo(new int[] {1, 2, 3});
    }

    private void callFoo(final int[] values)
    {
        final Class[] parameters;

        parameters = new Class[values.length];

        for(int i = 0; i < parameters.length; i++)
        {
            parameters[i] = int.class;
        }

        try
        {
            final Method   method;
            final Object[] args;

            method = Main.class.getDeclaredMethod("foo", parameters);
            args   = new Object[values.length];

            for(int i = 0; i < args.length; i++)
            {
                args[i] = Integer.valueOf(values[i]);
            }

            method.invoke(this, args);
        }
        catch(final IllegalAccessException ex)
        {
            ex.printStackTrace();
        }
        catch(final IllegalArgumentException ex)
        {
            ex.printStackTrace();
        }
        catch(final InvocationTargetException ex)
        {
            ex.printStackTrace();
        }
        catch(final NoSuchMethodException ex)
        {
            ex.printStackTrace();
        }
        catch(final SecurityException ex)
        {
            ex.printStackTrace();
        }
    }

    private void foo(int a)
    {
        System.out.println("foo(" + a + ")");
    }

    private void foo(int a, int b)
    {
        System.out.println("foo(" + a + ", " + b + ")");
    }

    private void foo(int a, int b, int c)
    {
        System.out.println("foo(" + a + ", " + b + ", " + c + ")");
    }
}

Edit... last one - this one will work for any method (you pass it the name of the method). This is the least safe one on the bunch - a typo in the name can ruin your day :-)

public class Main
{
    public static void main(String[] args)
    {
        final Main main;

        main = new Main();
        main.call("foo", new int[] {1});
        main.call("foo", new int[] {1, 2});
        main.call("foo", new int[] {1, 2, 3});
        main.call("bar", new int[] {1});
        main.call("bar", new int[] {1, 2});
        main.call("bar", new int[] {1, 2, 3});
    }

    private void call(final String methodName, 
                      final int[]  values)
    {
        final Class[] parameters;

        parameters = new Class[values.length];

        for(int i = 0; i < parameters.length; i++)
        {
            parameters[i] = int.class;
        }

        try
        {
            final Method   method;
            final Object[] args;

            method = Main.class.getDeclaredMethod(methodName, parameters);
            args   = new Object[values.length];

            for(int i = 0; i < args.length; i++)
            {
                args[i] = Integer.valueOf(values[i]);
            }

            method.invoke(this, args);
        }
        catch(final IllegalAccessException ex)
        {
            ex.printStackTrace();
        }
        catch(final IllegalArgumentException ex)
        {
            ex.printStackTrace();
        }
        catch(final InvocationTargetException ex)
        {
            ex.printStackTrace();
        }
        catch(final NoSuchMethodException ex)
        {
            ex.printStackTrace();
        }
        catch(final SecurityException ex)
        {
            ex.printStackTrace();
        }
    }

    private void foo(int a)
    {
        System.out.println("foo(" + a + ")");
    }

    private void foo(int a, int b)
    {
        System.out.println("foo(" + a + ", " + b + ")");
    }

    private void foo(int a, int b, int c)
    {
        System.out.println("foo(" + a + ", " + b + ", " + c + ")");
    }

    private void bar(int a)
    {
        System.out.println("bar(" + a + ")");
    }

    private void bar(int a, int b)
    {
        System.out.println("bar(" + a + ", " + b + ")");
    }

    private void bar(int a, int b, int c)
    {
        System.out.println("bar(" + a + ", " + b + ", " + c + ")");
    }
}
TofuBeer
The methods I'm calling are part of a maths distribution library. Theres like 20 different functions and around 3-4 overloaded for each one. I Just wished to avoid having to do a massive if/switch statements to figure out each one
Ying Chan
Well I have given you the code for two ways... I would suggest using the non-reflection version and make "callXXX" methods to do the work. If you really don't want to do that use the reflection one.
TofuBeer
thankyou for that. I'm taking a look at both examples now
Ying Chan