I am using a simulator to play craps and I am trying to return two values from the same method (or rather I would like to).

When I wrote my return statement I simply tried putting "&" which compiled and runs properly; but I have no way of accessing the second returned value.

public static int crapsGame(){ int myPoint; int gameStatus = rollagain; int d1,d2; int rolls=1; d1 = rollDice(); d2 = rollDice(); switch ( d1+d2 ) { case 7: case 11: gameStatus = win; break; case 2: case 3: case 12: gameStatus = loss; break; default: myPoint = d1+d2; do { d1=rollDice(); d2=rollDice(); rolls++; if ( d1+d2 == myPoint ) gameStatus = win; else if ( d1+d2 == 7 ) gameStatus = loss; } while (gameStatus == rollagain); } // end of switch return gameStatus & rolls; } 

When I return the value as:

gameStatus=crapsGame(); 

It appropriately sets the varaible to win or lose but if I try something as simple as following that statement with:

rolls=crapsGame(); 

It is assigned the same value as gamestatus...a 0 or a 1 (win or lose). Any way that I can access the second returned value? Or is there a completely different way to go about it?

7

6 Answers

Create your own value holder object to hold both values, then return it.

return new ValueHolder(gameStatus, rolls); 

It's possible to return an array with multiple values, but that's cryptic and it does nothing for readability. It's much easier to understand what this means...

valueHolder.getGameStatus() 

than what this means.

intArray[0] 
3

returning gameStatus & rolls means "return the bitwise and of gameStatus and rolls" which probably is not what you want

you have some options here:

  • return an array
  • create a class that represents the response with a property for each value and return an instance
  • use one of the many java collections to return the values (probably lists or maps)
2

You can return an array of values or a Collection of values.

Is it possible to return more than one value from a method in Java?

No it is not. Java allows only one value to be returned. This restriction is hard-wired into the language.

However, there are a few approaches to deal with this restriction:

  • Write a light-weight "holder" class with fields for the multiple values you want to return, and create and return an instance of that class.
  • Return a Map containing the values. The problem with this (and the next) approach is that you are straying into an area that requires runtime type checking ... and that can lead to fragility.
  • Return an array containing the values. The array has to have a base type that will accommodate the types of all of the values.
  • If this is a method on an object, then add some fields on the same object and methods that allow the caller to pick up "auxiliary results" from the last call. (For example, the JDBC ResultSet class does this to allow a client to determine if the value just retrieved was a NULL.) The problem is that this makes the class non-reentrant at the instance level.
  • (You could even return extra results in statics, but it is a really bad idea. It makes the class non-reentrant across all instances, not to mention all of the other badnesses associated with misused statics.)

Of these, the first option is the cleanest. If you are worried about the overhead of creating holder instances, etc, you could consider reusing the instances; e.g. have the caller pass an existing "holder" to the called method into which the results should be placed.

The best practice for an OOP approach is to return an Object. An object that contains all the values you want.

Example:

class Main { public static void main(String[] args) { MyResponse response = requestResponse(); System.out.println( response.toString() ); } private static MyResponse requestResponse() { return new MyResponse( "this is first arg", "this is second arg" ); } } class MyResponse { private String x, y; public MyResponse( String x, String y ) { this.x = x; this.y = y; } @Override public String toString() { return "x: " + x + "\t y: " + y; } } 

If you want an even more scalable approach then you have to use JSON responses. (let me know if you want an example with JSON too)

2

You can following ways to do this:

  1. Use a Container class, for example

    public class GameStatusAndRolls { String gameStatus; String rolls; ... // constructor and getter/setter } public static GameStatusAndRolls crapsGame(String gameStatus, String rolls) { return new GameStatusAndRolls(gameStatus, rolls); } public static void main(String[] args) { ... GameStatusAndRolls gameStatusAndRolls = crapsGame(gameStatus, rolls); gameStatusAndRolls.getGameStatus(); 
  2. Use List or an array, for example

    public static List<Integer> crapsGame(String gameStatus, String rolls) { return Arrays.asList(gameStatus, rolls); } private static final int GAME_STATUS = 0; private static final int ROOLS = 0; public static void main(String[] args) { ... List<Integer> list = crapsGame(gameStatus, rolls); ... list.get(0)...list.get(GAME_STATUS); ... list.get(1)...list.get(ROOLS); 

    or

    public static String[] crapsGame(String gameStatus, String rolls) { return new String[] {gameStatus, rolls}; } private static final int GAME_STATUS = 0; private static final int ROOLS = 0; public static void main(String[] args) { ... String[] array = crapsGame(gameStatus, rolls); ... array[0]...array[GAME_STATUS]; ... array[1]...array[ROOLS]; 
  3. Use Map, for example

    public static Map<String, String> crapsGame(String gameStatus, String rolls) { Map<String, String> result = new HashMap<>(2); result.put("gameStatus", gameStatus); result.put("rolls", rolls); return result; } public static void main(String[] args) { ... Map map = crapsGame(gameStatus, rolls); ... map.get("gameStatus")...map.get("rolls");