2010-05-14 7 views
123

J'essaye de retourner 2 valeurs d'une méthode de Java mais j'obtiens ces erreurs. Voici mon code:Comment retourner 2 valeurs d'une méthode 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); 
} 

Erreur:

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 Résultat: 1

+1

Si ce double aller dans l'autre sens? La réponse ici semble mieux. –

Répondre

178

au lieu de retourner un tableau qui contient les deux valeurs ou En utilisant une classe générique Pair, envisagez de créer une classe qui représente le résultat que vous souhaitez renvoyer et renvoyez une instance de cette classe. Donnez un nom significatif à la classe. Les avantages de cette approche par rapport à l'utilisation d'un tableau sont la sécurité de type et cela rendra votre programme beaucoup plus facile à comprendre.

Remarque: Une classe générique Pair, comme proposé dans certaines des autres réponses ici, vous donne également la sécurité de type, mais ne transmet pas ce que le résultat représente.

Exemple (qui n'utilise pas vraiment des noms significatifs):

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

Ce serait ma route préférée - probablement la paire de nombres a une signification, et ce serait bien si le type de retour représentait cela. – Armand

+1

Vous pouvez utiliser SimpleEntry depuis java.util.AbstractMap.SimpleEntry et utilisez-le avec getKey() pour obtenir l'objet 1 et getValue() pour obtenir l'objet 2 – Crystalonics

+11

Je crois fermement que Java devrait vous permettre de renvoyer plusieurs valeurs. Ce serait plus rapide (moins d'objets créés) et ne nécessiterait pas de classes supplémentaires (code boursouflé) chaque fois que vous voudriez faire quelque chose de différent. Je ne vois aucun inconvénient, peut-être que quelqu'un peut m'éclairer? –

5

vous devez utiliser les collections pour retourner plus d'un retour des valeurs

dans votre cas, vous écrivez votre code en tant que

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 ne prend pas en charge les retours de plusieurs valeurs. Renvoie un tableau de valeurs.

// 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

Merci. Je l'ai!! –

+3

C'est presque toujours la mauvaise chose à faire, surtout si les types des deux valeurs de résultat sont différents. –

+0

@KevinSitze pourquoi est-ce faux? –

19

Vous ne pouvez retourner une valeur en Java, donc la plus élégante façon est comme ceci:

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

est ici une version mise à jour de votre code:

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

Essayez ceci:

// 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

Vous pourriez implémenter un Pair générique si vous êtes sûr que vous avez juste besoin de retourner deux valeurs:

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 

et ont le retour de méthode qui Pair:

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

Vous pouvez également envoyer des objets mutables en tant que paramètres, si vous utilisez des méthodes pour les modifier puis ils seront modifiés lorsque vous revenez de la fonction. Ça ne marchera pas sur des trucs comme Float, car c'est immuable.

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

Le résultat est: 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

Vous n'avez pas besoin de créer votre propre classe pour revenir deux valeurs différentes.Utilisez simplement un HashMap comme ceci:

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

Vous avez même l'avantage de la sécurité de type.

+1

Vous n'avez même pas besoin d'un HashMap, utilisez simplement un SimpleEntry! – Xerus

2

À mon avis, le mieux est de créer une nouvelle classe qui constructeur est la fonction dont vous avez besoin, par exemple:

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; 
     } 
    } 

Ensuite, utilisez simplement le constructeur que vous utilisez la fonction:

pairReturn pR = new pairReturn(15); 

et vous pouvez utiliser pR.sth1, pR.sth2 comme « 2 résultats de la fonction »

3

Utilisez une paire/Tuple objet de type, vous ne même pas besoin de créer un si u dépendent des commons-lang Apache. Utilisez simplement la classe Pair.

-1

Il y a évidemment plusieurs façons de le faire, mais après avoir expérimenté, j'ai trouvé cette solution assez facile. Je vais coller le code pour lancer 2 dés et retourner les deux résultats, ensuite je vais vous expliquer.

Le code source:

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)); 

L'explication:

Après avoir découvert que déclarant un simple double méthode statique ne fonctionnerait pas, je trouve que vous pouvez utiliser une valeur de chaîne pour mettre fin à la méthode sans erreur de compilation, tout en vous donnant le résultat que vous voulez. De cette façon, vous pouvez passer deux valeurs doubles (vos valeurs de dé) dans la méthode Chaîne statique et lui permettre de renvoyer vos deux dés lancés (doubles) dans une chaîne, et non deux doubles séparés. Lorsque vous invoquez la méthode dans la dernière ligne de code, j'ai passé deux 0 comme arguments afin que les dés puissent être lancés uniformément, et parce que la méthode nécessite deux arguments doubles. Si vous avez des questions, je peux répondre à toute question concernant le code et l'explication ci-dessus.

+2

Êtes-vous sérieusement "renvoyer" les valeurs en les imprimant avec 'System.out.printf()'? – cosimo

+0

Techniquement, il ne retourne pas réellement les valeurs dans l'instruction de retour, mais ce programme fonctionne pour lancer deux dés en prenant deux arguments, et en agissant sur eux pour renvoyer les deux jets de dés aléatoires résultants. Est-ce un problème? – AceTFR

+0

Ceci est ma première réponse SO. Je me considère encore comme une recrue, donc j'expérimente de nouvelles idées. Cette solution est-elle un problème? – AceTFR

0

Retourne un tableau d'objets

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

Je suis curieux de savoir pourquoi personne est venu avec la solution de rappel plus élégante. Ainsi, au lieu d'utiliser un type de retour, vous utilisez un gestionnaire passé dans la méthode en tant qu'argument. L'exemple ci-dessous présente les deux approches contrastées. Je sais lequel des deux est le plus élégant pour moi. :-)

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); 
     }); 
    } 
} 
Questions connexes