2010-10-22 24 views
7

¿Hay alguna forma de convertir una matriz en una lista de parámetros?Java Convert Array a los parámetros

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 
} 

Quiero convertir "a" en una lista de parámetros/argumentos para que llame automáticamente a la función adecuada.

+0

Y ¿por qué no usar 'void MyPrint (int x ...)' como se sugiere? – Cristian

+0

porque no puedo modificar la función. –

+0

¿MyPrint solo va a tomar 1, 2 o 3 argumentos? – shoebox639

Respuesta

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

void MyPrint(int... x){ 
//Do Stuff to arguments (accessing them by its index) 
} 
+0

digamos que MyPrint es una función sobrecargada. Quiero poder convertir mi matriz en parámetros, así puedo llamar a un método específico sobrecargado –

+0

no lo entiendo ... ¿podría explicarme un poco más? – Cristian

+0

modifiqué mi pregunta anterior –

0

En resumen, esto realmente no es posible. La única forma de tomar una cantidad variable de argumentos es con el constructo int...x. De lo contrario, debe averiguar cuántos elementos hay en a y luego averiguar a cuál llamar.

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

Sería extremadamente extraño hacer lo que está tratando de hacer. Si está buscando una forma general de hacerlo, debería profundizar en la reflexión (java.lang.reflect). Si realmente tiene una matriz/colección con 1, 2 o 3 entradas y desea llamar a un método diferente basado en eso, simplemente escriba un método que descubra el número de valores en la "cosa" y llame al método apropiado.

¿Puede decirnos por qué quiere hacer esto?

Editar:

Código para el camino duro codificado:

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 + ")"); 
    } 
} 

Aquí está la versión de reflexión (que no se ocuparía de los errores a través de printStackTrace, pero es un punto de partida):

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 + ")"); 
    } 
} 

Editar ... el último - este funcionará para cualquier método (le paso el nombre del método). Este es el menos seguro en el racimo - un error tipográfico en el nombre puede arruinar su día :-)

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 + ")"); 
    } 
} 
+0

Los métodos que estoy llamando son parte de una biblioteca de distribución de matemáticas. Hay como 20 funciones diferentes y alrededor de 3-4 sobrecargadas para cada una. Solo quería evitar tener que hacer una declaración masiva de si/cambiar para descubrir cada uno –

+0

Bueno, le he dado el código de dos maneras ... Sugeriría usar la versión no reflectante y hacer los métodos "callXXX" para hacer la obra. Si realmente no quieres hacer eso, usa el de reflexión. – TofuBeer

+0

gracias por eso. Estoy echando un vistazo a ambos ejemplos ahora –