【问题标题】:How to return 2 values from a Java method?如何从 Java 方法返回 2 个值?
【发布时间】:2011-02-19 10:06:55
【问题描述】:

我试图从 Java 方法返回 2 个值,但我得到了这些错误。这是我的代码:

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

错误:

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 结果:1

【问题讨论】:

  • 副本应该反过来吗?这里的答案似乎更好。

标签: java function return-value


【解决方案1】:

首先,如果 Java 有用于返回多个值的元组会更好。

其次,编写最简单的Pair 类,或使用数组。

但是,如果您确实需要返回一对,请考虑它代表什么概念(从它的字段名开始,然后是类名) - 以及它是否发挥了比您想象的更大的作用,以及如果它有助于您的整体设计对其进行明确的抽象。也许是code hint...
请注意:我并不是武断地说它有帮助,而只是看看,看看是否有...或是否没有。

【讨论】:

    【解决方案2】:

    这是使用 SimpleEntry 的真正简单而简短的解决方案:

    AbstractMap.Entry<String, Float> myTwoCents=new AbstractMap.SimpleEntry<>("maximum possible performance reached" , 99.9f);
    
    String question=myTwoCents.getKey();
    Float answer=myTwoCents.getValue();
    

    仅使用 Java 内置函数,它具有类型安全的好处。

    【讨论】:

      【解决方案3】:

      我很好奇为什么没有人想出更优雅的回调解决方案。因此,不是使用返回类型,而是使用作为参数传递给方法的处理程序。下面的例子有两种截然不同的方法。我知道这两者中哪一个对我来说更优雅。 :-)

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

      【讨论】:

        【解决方案4】:

        返回一个对象数组

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

        【讨论】:

          【解决方案5】:

          如果你确定只需要返回两个值,你可以实现一个通用的Pair

          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
          

          然后让方法返回 Pair:

          public Pair<Object, Object> getSomePair();
          

          【讨论】:

          • 这个方法的返回结果是什么样的?
          • 类似于:pair = new Pair(thing1, thing2)....return pair;
          【解决方案6】:

          使用 Pair/Tuple 类型的对象,如果你依赖于 Apache commons-lang,你甚至不需要创建一个。只需使用Pair 类。

          【讨论】:

            【解决方案7】:

            在我看来,最好的方法是创建一个新类,构造函数就是你需要的函数,例如:

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

            然后像使用函数一样简单地使用构造函数:

            pairReturn pR = new pairReturn(15);
            

            您可以使用 pR.sth1、pR.sth2 作为“函数的 2 个结果”

            【讨论】:

              【解决方案8】:

              您无需创建自己的类即可返回两个不同的值。只需使用这样的 HashMap:

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

              您甚至可以享受类型安全的好处。

              【讨论】:

              • 你甚至不需要 HashMap,只需使用 SimpleEntry!
              • 为什么是HashMap,请问?这似乎是一种奇怪的数据结构。
              • @Neil Chowdhury 没有其他原因,因为它是一个方便的内置类,带有两个可定义的参数。正如 Xerus 所指出的,AbstractMap.SimpleEntry 是这里更轻量级的选项。请看下方对应答案!
              【解决方案9】:
              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
              

              【讨论】:

                【解决方案10】:

                您也可以将可变对象作为参数发送,如果您使用方法修改它们,那么当您从函数返回时它们将被修改。它不适用于 Float 之类的东西,因为它是不可变的。

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

                结果是: 罗格

                【讨论】:

                  【解决方案11】:

                  不要返回包含两个值的数组或使用通用Pair 类,而是考虑创建一个表示您要返回的结果的类,并返回该类的一个实例。给班级起一个有意义的名字。与使用数组相比,这种方法的好处是类型安全,它会让你的程序更容易理解。

                  注意:一个通用的 Pair 类,正如这里的一些其他答案所建议的,也为您提供类型安全,但不传达结果代表什么。

                  示例(没有使用真正有意义的名称):

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

                  【讨论】:

                  • 这将是我的首选路线 - 大概这对数字有一些意义,如果返回类型代表这一点会很好。
                  • 您可以使用 java.util.AbstractMap.SimpleEntry 中的 SimpleEntry 并将其与 getKey() 一起使用以获取对象 1 和 getValue() 以获取对象 2
                  • 我非常强烈地觉得Java应该允许你返回多个值。它会更快(创建的对象更少),并且每次您想做一些不同的事情时都不需要额外的类(臃肿的代码)。我没有看到任何缺点,也许有人可以启发我?
                  • 这只是针对所提问题的一种解决方法,它仍然代表“如何像在 Python 中一样从方法返回 2 个值”。
                  • @AnumSheraz “如何......就像在 Python 中一样”的答案是:你没有,因为 Java 没有这样的语言特性......
                  【解决方案12】:

                  在Java中你只能返回一个值,所以最简洁的方法是这样的:

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

                  这是您的代码的更新版本:

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

                  【讨论】:

                    【解决方案13】:

                    Java 不支持多值返回。返回一个值数组。

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

                    【讨论】:

                    • 这几乎总是错误的做法,尤其是当两个结果值的类型不同时。
                    • @BarAkiva,它出错的原因是因为你失去了类型安全性。如果您要返回同质类型的值,那么您应该始终更喜欢 List 而不是数组。特别是,如果您正在处理泛型值,则 List 总是优先于 T[] 作为返回值,因为您始终可以在泛型类型上构造 List 而不是数组;你不能这样做:“new T[length];”此处为不同类型创建 Pair 类的方法是异构类型的更好选择。
                    【解决方案14】:

                    你必须使用集合来返回多个返回值

                    在您的情况下,您将代码编写为

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

                    【讨论】:

                      猜你喜欢
                      • 2014-05-27
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2012-01-04
                      • 1970-01-01
                      • 1970-01-01
                      • 2012-09-20
                      • 2014-02-28
                      相关资源
                      最近更新 更多