229

I am trying to return 2 values from a Java method but I get these errors. Here is my code:

// 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 Result: 1

Michael
  • 3,093
  • 7
  • 39
  • 83
javaLearner.java
  • 2,441
  • 2
  • 18
  • 12

16 Answers16

288

Instead of returning an array that contains the two values or using a generic Pair class, consider creating a class that represents the result that you want to return, and return an instance of that class. Give the class a meaningful name. The benefits of this approach over using an array are type safety and it will make your program much easier to understand.

Note: A generic Pair class, as proposed in some of the other answers here, also gives you type safety, but doesn't convey what the result represents.

Example (which doesn't use really meaningful names):

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());
}
Jesper
  • 202,709
  • 46
  • 318
  • 350
  • 1
    This would be my preferred route - presumably the pair of numbers has some meaning, and it would be nice if the return type represented this. – Armand May 14 '10 at 11:50
  • 4
    You can use SimpleEntry from java.util.AbstractMap.SimpleEntry and use it with getKey() to get object 1 and getValue() to get object 2 – Crystalonics Apr 28 '16 at 18:03
  • 74
    I feel very strongly that Java should allow you to return multiple values. It would be faster (fewer objects created) and wouldn't require extra classes (bloated code) every time you want to do something a bit different. I don't see any downsides, perhaps someone can enlighten me? – Chris Seline Jun 24 '16 at 20:09
  • This is just a work-around for the asked question, which still stands "how to return 2 values from method just like we do in Python". – Anum Sheraz Jul 11 '18 at 17:12
  • 6
    @AnumSheraz The answer to "how to ... just like in Python" is: you don't, because Java does not have such a language feature... – Jesper Jul 11 '18 at 20:21
  • In C++17, language support has been added for this, and is called "structured binding declarations". It would be great if Java could add something similar. – AffluentOwl Sep 27 '18 at 17:56
  • 1
    Java might get a convenient way to return multiple values from a method in the future, based on pattern matching with records. But this is not yet available in Java 17. – Jesper Mar 08 '22 at 10:11
  • And that's why Golang was created :) – Nikhil Goyal Jun 10 '22 at 10:39
85

Java does not support multi-value returns. Return an array of values.

// 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]);
}
Matt
  • 43,482
  • 6
  • 101
  • 102
  • 15
    This is almost always the wrong thing to do, especially if the types of the two result values are different. – Kevin Sitze Feb 09 '17 at 21:27
  • 7
    @BarAkiva, the reason it is wrong is because you loose type safety. If you're returning values of a homogenous type then you should always prefer a List over an array. In particular, if you're dealing with generic values then a List is always preferred as a return value over T[] because you can always construct a List on a generic type but never an array; you cannot do this: "new T[length];" The approach of creating a Pair class as indicated here for disparate types is a better option for heterogenous types. – Kevin Sitze Sep 07 '17 at 06:14
52

You could implement a generic Pair if you are sure that you just need to return two values:

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

and then have the method return that Pair:

public Pair<Object, Object> getSomePair();
Damian Krawczyk
  • 2,241
  • 1
  • 18
  • 26
Lars Andren
  • 8,601
  • 7
  • 41
  • 56
28

You can only return one value in Java, so the neatest way is like this:

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

Here's an updated version of your 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;
    }
}
richj
  • 7,499
  • 3
  • 32
  • 50
14

Here is the really simple and short solution with SimpleEntry:

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

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

Only uses Java built in functions and it comes with the type safty benefit.

8

Use a Pair/Tuple type object , you don't even need to create one if u depend on Apache commons-lang. Just use the Pair class.

UserF40
  • 3,533
  • 2
  • 23
  • 34
6

you have to use collections to return more then one return values

in your case you write your code as

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();
    }
GuruKulki
  • 25,776
  • 50
  • 140
  • 201
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
siva
  • 57
  • 1
3

Return an Array Of Objects

private static Object[] f () 
{ 
     double x =1.0;  
     int y= 2 ;
     return new Object[]{Double.valueOf(x),Integer.valueOf(y)};  
}
M.C.
  • 1,765
  • 3
  • 29
  • 31
3

I'm curious as to why nobody has come up with the more elegant callback solution. So instead of using a return type you use a handler passed into the method as an argument. The example below has the two contrasting approaches. I know which of the two is more elegant to me. :-)

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

You can create a record (available since Java 14) to return the values with type safety, naming and brevity.

public record MyResult(int number1, int number2) {
}

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.number1() + result.number2());
}
g t
  • 7,287
  • 7
  • 50
  • 85
2

You don't need to create your own class to return two different values. Just use a HashMap like this:

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

You even have the benefit of type safety.

  • 3
    You don't even need a HashMap, just use a SimpleEntry! – xeruf Oct 10 '17 at 10:06
  • Why a HashMap, may I ask? That seems like a strange data structure to use here. – Neil Jul 12 '18 at 05:04
  • @Neil Chowdhury No other reason than because it is a conveniently built-in Class taking two definable parameters. As Xerus pointed out, AbstractMap.SimpleEntry is the more lightweight option here. Please see the corresponding answer below! – Code ninetyninepointnine Jul 15 '18 at 07:43
2

In my opinion the best is to create a new class which constructor is the function you need, e.g.:

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

Then simply use the constructor as you would use the function:

pairReturn pR = new pairReturn(15);

and you can use pR.sth1, pR.sth2 as "2 results of the function"

Jacob
  • 21
  • 4
1

You also can send in mutable objects as parameters, if you use methods to modify them then they will be modified when you return from the function. It won't work on stuff like Float, since it is immutable.

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

The result is: Rutger

Andreas
  • 545
  • 1
  • 4
  • 16
0

First, it would be better if Java had tuples for returning multiple values.

Second, code the simplest possible Pair class, or use an array.

But, if you do need to return a pair, consider what concept it represents (starting with its field names, then class name) - and whether it plays a larger role than you thought, and if it would help your overall design to have an explicit abstraction for it. Maybe it's a code hint...
Please Note: I'm not dogmatically saying it will help, but just to look, to see if it does... or if it does not.

hyperpallium
  • 571
  • 5
  • 18
0

Option 1 : Use Pair

    import org.javatuples.Pair;
    Pair<Integer, Integer> pair =  Pair.with(1, 3);

    // Retrive Values
     System.out.println(pair.getValue0()) // 1
     System.out.println(pair.getValue1()) // 3

Option 2 Create a static object and add values in that:

static class Result{
  int first;
  int second;
  public Result(int first, int second){
    this.first =first;
    this.second =second;
  }
}
public static void main(String[] args) {
  Result result = new Result(1,3);
  System.out.println(result.first); // 1
  System.out.println(result.first);//3
}

Option 3 : Use List or Map.(List Maintain sequence.)

 List<Integer> list = Arrays.asList(1,3);
 list.get(0); // 1
 list.get(1); // 3
 

       
Sneha Mule
  • 641
  • 8
  • 6