如何从Java方法返回2个值?


179

我试图从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


1
那个副本应该反过来吗?答案似乎更好。
J理查德·斯内普

Answers:


239

不要返回包含两个值的数组或使用泛型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());
}

1
这将是我的首选路线-大概这对数字具有某些含义,并且如果返回类型表示这一点会很好。
阿曼德

3
您可以从java.util.AbstractMap.SimpleEntry中使用SimpleEntry <type_of_value_1,type_of_value_2>,并将其与getKey()一起使用来获取对象1,并通过getValue()来获取对象2
Crystalonics

45
我非常强烈地认为Java应该允许您返回多个值。这样会更快(创建的对象更少),并且每次您想做一些不同的事情时都不需要额外的类(膨胀的代码)。我看不到任何弊端,也许有人可以启发我?
克里斯·塞琳

这只是针对所提问题的一种解决方法,该问题仍然表示“如何像在Python中一样从方法中返回2个值”。
阿努姆·谢拉兹

4
@AnumSheraz对“如何……就像在Python中一样”的答案是:您没有,因为Java不具有这样的语言功能……
Jesper

74

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

7
这几乎总是错误的做法,尤其是当两个结果值的类型不同时。
凯文·西兹

7
@BarAkiva,错误的原因是因为您松开了类型安全性。如果要返回同构类型的值,则应始终首选使用List而不是数组。特别是,如果您要处理通用值,那么List <T>总是比T []更喜欢作为返回值,因为您可以始终在通用类型上构造List,但不能构造数组。您不能这样做:“ new T [length];” 如此处所示,为异构类型创建Pair类的方法对于异构类型是更好的选择。
凯文·西兹

41

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

该方法的返回结果是什么样的?
Jwan622

类似于:pair = new Pair(thing1,something2).... return pair;
拉尔斯·安德伦

27

您只能在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;
    }
}

8

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

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

String question=myTwoCents.getKey();
Float answer=myTwoCents.getValue();

仅使用Java内置函数,并且具有类型安全性好处。


6

您必须使用集合来返回一个以上的返回值

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

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

4
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

4

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


为什么不更支持?
Rauni Lillemets

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

2

您无需创建自己的类即可返回两个不同的值。像这样使用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);
}

您甚至受益于类型安全。


2
您甚至不需要HashMap,只需使用SimpleEntry!
Xerus

为什么要使用HashMap?在这里似乎使用了一个奇怪的数据结构。
尼尔·乔杜里

@Neil Chowdhury除了它是带有两个可定义参数的便捷内置类之外,没有其他原因。正如Xerus所指出的,这里的AbstractMap.SimpleEntry是更轻量级的选项。请在下面查看相应的答案!
代码ninetyninepointnine

2

我认为最好的办法是创建一个新类,该类的构造函数就是您需要的功能,例如:

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个结果”


1

您还可以将可变对象作为参数发送,如果使用方法修改它们,则从函数返回时将对其进行修改。由于它是不可变的,因此不适用于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");
     }
}

其结果是:Rutger


1

返回对象数组

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

0

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

第二,编写最简单的代码 Pair类,或使用数组。

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


-7

这就是您在JS:中的方法 return { objA, valueB }。我知道这是题外话,但是在看到必须在Java中实现一个全新的类之后,我不能不发表此评论。JavaScript-不要浪费生命,开始编写脚本!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.