2010-05-14 15 views
123

Estoy tratando de devolver 2 valores desde un método Java pero obtengo estos errores. Aquí está mi código:¿Cómo devolver 2 valores desde un método Java?

// Method code 
public static int something(){ 
    int number1 = 1; 
    int number2 = 2; 

    return number1, number2; 
} 

// Main method code 
public static void main(String[] args) { 
    something(); 
    System.out.println(number1 + number2); 
} 

error:

Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - missing return statement 
    at assignment.Main.something(Main.java:86) 
    at assignment.Main.main(Main.java:53) 

Java Resultado: 1

+1

¿Ese duplicado debe ser al revés? La respuesta aquí parece mejor. –

Respuesta

178

En lugar de devolver una matriz que contiene los dos valores o utilizando una clase genérica Pair, considere la creación de una clase que represente el resultado que desea devolver, y devuelva una instancia de esa clase. Dale a la clase un nombre significativo. Los beneficios de este enfoque sobre el uso de una matriz son de seguridad tipo y hará que su programa sea mucho más fácil de entender.

Nota: Una clase genérica Pair, como se propone en algunas de las otras respuestas aquí, también le da seguridad de tipo, pero no transmite lo que representa el resultado.

Ejemplo (que no utiliza nombres muy significativos):

final class MyResult { 
    private final int first; 
    private final int second; 

    public MyResult(int first, int second) { 
     this.first = first; 
     this.second = second; 
    } 

    public int getFirst() { 
     return first; 
    } 

    public int getSecond() { 
     return second; 
    } 
} 

// ... 

public static MyResult something() { 
    int number1 = 1; 
    int number2 = 2; 

    return new MyResult(number1, number2); 
} 

public static void main(String[] args) { 
    MyResult result = something(); 
    System.out.println(result.getFirst() + result.getSecond()); 
} 
+1

Esta sería mi ruta preferida, presumiblemente el par de números tiene algún significado, y sería bueno si el tipo de retorno representara esto. – Armand

+1

Puede usar SimpleEntry from java.util.AbstractMap.SimpleEntry y úselo con getKey() para obtener el objeto 1 y getValue() para obtener el objeto 2 – Crystalonics

+11

Creo firmemente que Java debería permitirle devolver varios valores. Sería más rápido (se crearían menos objetos) y no requeriría clases adicionales (código inflado) cada vez que desea hacer algo un poco diferente. No veo inconvenientes, tal vez alguien me puede iluminar? –

5

usted tiene que utilizar colecciones para volver más de una vuelta valora

en su caso se escribe su código como

public static List something(){ 
     List<Integer> list = new ArrayList<Integer>(); 
     int number1 = 1; 
     int number2 = 2; 
     list.add(number1); 
     list.add(number2); 
     return list; 
    } 

    // Main class code 
    public static void main(String[] args) { 
     something(); 
     List<Integer> numList = something(); 
    } 
57

Java no admite devoluciones de múltiples valores. Devuelve una matriz de valores.

// Function code 
public static int[] something(){ 
    int number1 = 1; 
    int number2 = 2; 
    return new int[] {number1, number2}; 
} 

// Main class code 
public static void main(String[] args) { 
    int result[] = something(); 
    System.out.println(result[0] + result[1]); 
} 
+0

Gracias. ¡¡Lo tengo!! –

+3

Esto casi siempre es lo incorrecto, especialmente si los tipos de los dos valores de resultado son diferentes. –

+0

@KevinSitze ¿por qué está mal? –

19

Sólo puede volver un valor en Java, por lo que la manera más ordenada es la siguiente:

return new Pair<Integer>(number1, number2); 

Aquí es una versión actualizada de su código:

public class Scratch 
{ 
    // Function code 
    public static Pair<Integer> something() { 
     int number1 = 1; 
     int number2 = 2; 
     return new Pair<Integer>(number1, number2); 
    } 

    // Main class code 
    public static void main(String[] args) { 
     Pair<Integer> pair = something(); 
     System.out.println(pair.first() + pair.second()); 
    } 
} 

class Pair<T> { 
    private final T m_first; 
    private final T m_second; 

    public Pair(T first, T second) { 
     m_first = first; 
     m_second = second; 
    } 

    public T first() { 
     return m_first; 
    } 

    public T second() { 
     return m_second; 
    } 
} 
7

Prueba esto:

// Function code 
public static int[] something(){ 
    int number1 = 1; 
    int number2 = 2; 
    return new int[] {number1, number2}; 
} 

// Main class code 
public static void main(String[] args) { 
    int[] ret = something(); 
    System.out.println(ret[0] + ret[1]); 
} 
30

Puede implementar un genérico Pair si está seguro de que sólo tiene que devolver dos valores:

public class Pair<U, V> { 

/** 
    * The first element of this <code>Pair</code> 
    */ 
    private U first; 

    /** 
    * The second element of this <code>Pair</code> 
    */ 
    private V second; 

    /** 
    * Constructs a new <code>Pair</code> with the given values. 
    * 
    * @param first the first element 
    * @param second the second element 
    */ 
    public Pair(U first, V second) { 

     this.first = first; 
     this.second = second; 
    } 

//getter for first and second 

y luego tener el método de retorno que Pair:

public Pair<Object, Object> getSomePair(); 
1

También puede enviar en objetos mutables como parámetros, si utiliza los métodos de modificarlos entonces van a ser modificados cuando regrese de la función. No funcionará en cosas como Float, ya que es inmutable.

public class HelloWorld{ 

    public static void main(String []args){ 
     HelloWorld world = new HelloWorld(); 

     world.run(); 
    } 



    private class Dog 
    { 
     private String name; 
     public void setName(String s) 
     { 
      name = s; 
     } 
     public String getName() { return name;} 
     public Dog(String name) 
     { 
      setName(name); 
     } 
    } 

    public void run() 
    { 
     Dog newDog = new Dog("John"); 
     nameThatDog(newDog); 
     System.out.println(newDog.getName()); 
    } 


    public void nameThatDog(Dog dog) 
    { 
     dog.setName("Rutger"); 
    } 
} 

El resultado es: Rutger

2
public class Mulretun 
{ 
    public String name;; 
    public String location; 
    public String[] getExample() 
    { 
     String ar[] = new String[2]; 
     ar[0]="siva"; 
     ar[1]="dallas"; 
     return ar; //returning two values at once 
    } 
    public static void main(String[] args) 
    { 
     Mulretun m=new Mulretun(); 
     String ar[] =m.getExample(); 
     int i; 
     for(i=0;i<ar.length;i++) 
     System.out.println("return values are: " + ar[i]);  

    } 
} 

o/p: 
return values are: siva 
return values are: dallas 
2

No es necesario para crear su propia clase para devolver dos valores diferentes.Sólo tiene que utilizar un HashMap como esto:

private HashMap<Toy, GameLevel> getToyAndLevelOfSpatial(Spatial spatial) 
{ 
    Toy toyWithSpatial = firstValue; 
    GameLevel levelToyFound = secondValue; 

    HashMap<Toy,GameLevel> hm=new HashMap<>(); 
    hm.put(toyWithSpatial, levelToyFound); 
    return hm; 
} 

private void findStuff() 
{ 
    HashMap<Toy, GameLevel> hm = getToyAndLevelOfSpatial(spatial); 
    Toy firstValue = hm.keySet().iterator().next(); 
    GameLevel secondValue = hm.get(firstValue); 
} 

Incluso tienen el beneficio de la seguridad de tipos.

+1

¡Ni siquiera necesita un HashMap, solo use un SimpleEntry! – Xerus

2

En mi opinión, el mejor es crear una nueva clase que el constructor es la función que necesita, por ejemplo:

public class pairReturn{ 
     //name your parameters: 
     public int sth1; 
     public double sth2; 
     public pairReturn(int param){ 
      //place the code of your function, e.g.: 
      sth1=param*5; 
      sth2=param*10; 
     } 
    } 

Entonces sólo tiene que utilizar el constructor de igual modo que la función:

pairReturn pR = new pairReturn(15); 

y puede usar pR.sth1, pR.sth2 como "2 resultados de la función"

3

Use un objeto de tipo Pair/Tuple, ni siquiera necesita crear uno si depende de Apache commons-lang. Solo usa la clase Pair.

-1

Obviamente hay varias maneras de hacerlo, pero después de experimentar, he encontrado que esta solución es bastante fácil. Pegaré el código para lanzar 2 dados y devolver los dos resultados, luego lo explicaré.

El código fuente:

import java.lang.Math; 
import java.util.*; 

public class DiceRolling { 

    private static String roll2Dice(double dice1, double dice2) { 

     String methodSatisfier = ""; 

     dice1 = (Math.random()*6); 
     dice2 = (Math.random()*6); 

     if (dice1 < 1) { 
      dice1 = Math.ceil(dice1); 
     } 
     if (dice2 < 1) { 
      dice2 = Math.ceil(dice2); 
     } 


     System.out.printf("First die: %.0f\nSecond die: %.0f", dice1, dice2); 

     return methodSatisfier; 
    } 

    public static void main(String[] args) { 

     DiceRolling object = new DiceRolling(); 

     System.out.println(object.roll2Dice(0, 0)); 

La explicación:

Después de descubrir que la declaración de un simple método de doble estática no funcionaría, descubrí que se puede utilizar un valor de cadena para terminar la método sin un error de compilación, al tiempo que le da el resultado que desea. De esta forma, puede pasar dos valores dobles (sus valores de dados) en el método de Cadena estática y permitirle devolver sus dos dados enrollados (dobles) en una Cadena, no dos dobles por separado. Cuando invocas el método en la última línea de código, pasé dos ceros como argumentos para que los dados se puedan enrollar uniformemente, y porque el método necesita dos argumentos dobles. Si tiene alguna pregunta, puedo satisfacer más cualquier consulta sobre el código y la explicación anterior.

+2

¿En serio "devuelve" los valores imprimiéndolos con 'System.out.printf()'? – cosimo

+0

Técnicamente, en realidad no devuelve los valores en la declaración de devolución, pero este programa funciona para tirar dos dados tomando dos argumentos y actuando sobre ellos para devolver los dos tiradas de dados al azar resultantes. ¿Es esto un problema? – AceTFR

+0

Esta es mi primera respuesta SO. Todavía me considero un novato, así que solo estoy experimentando nuevas ideas. ¿Es esta solución un problema? – AceTFR

0

devolver una matriz de objetos

private static Object[] f() 
{ 
    double x =1.0; 
    int y= 2 ; 
    return new Object[]{Double.valueOf(x),Integer.valueOf(y)}; 
} 
0

Soy curioso en cuanto a por qué nadie ha llegado con la solución más elegante de devolución de llamada. Entonces, en lugar de utilizar un tipo de devolución, utiliza un controlador pasado al método como argumento. El siguiente ejemplo tiene los dos enfoques contrastantes. Sé cuál de los dos es más elegante para mí. :-)

public class DiceExample { 

    public interface Pair<T1, T2> { 
     T1 getLeft(); 

     T2 getRight(); 
    } 

    private Pair<Integer, Integer> rollDiceWithReturnType() { 

     double dice1 = (Math.random() * 6); 
     double dice2 = (Math.random() * 6); 

     return new Pair<Integer, Integer>() { 
      @Override 
      public Integer getLeft() { 
       return (int) Math.ceil(dice1); 
      } 

      @Override 
      public Integer getRight() { 
       return (int) Math.ceil(dice2); 
      } 
     }; 
    } 

    @FunctionalInterface 
    public interface ResultHandler { 
     void handleDice(int ceil, int ceil2); 
    } 

    private void rollDiceWithResultHandler(ResultHandler resultHandler) { 
     double dice1 = (Math.random() * 6); 
     double dice2 = (Math.random() * 6); 

     resultHandler.handleDice((int) Math.ceil(dice1), (int) Math.ceil(dice2)); 
    } 

    public static void main(String[] args) { 

     DiceExample object = new DiceExample(); 


     Pair<Integer, Integer> result = object.rollDiceWithReturnType(); 
     System.out.println("Dice 1: " + result.getLeft()); 
     System.out.println("Dice 2: " + result.getRight()); 

     object.rollDiceWithResultHandler((dice1, dice2) -> { 
      System.out.println("Dice 1: " + dice1); 
      System.out.println("Dice 2: " + dice2); 
     }); 
    } 
} 
Cuestiones relacionadas