11

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?

Michael MacDonald
  • 413
  • 2
  • 6
  • 17
  • use array of object or hashmap or model class – Daniel Robertus Mar 08 '13 at 01:39
  • 5
    No it is not. You can return an object though and that object can contain multiple properties – Benjamin Gruenbaum Mar 08 '13 at 01:39
  • You should return an int[]. Checkout http://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html – sissonb Mar 08 '13 at 01:40
  • @sissonb So I would return an array and assign index 1 as the gameStatus and the second index as number of rolls? And then return it to an existing array? where I could then access it? – Michael MacDonald Mar 08 '13 at 01:51
  • @OscarWilde yep, but remember index's of arrays start at 0. Also your method will need to change to `public static int[] crapsGame`. This is a more of a quick and dirty method to return the values. If this is going to turn into a large project then returning an object like @rgettman said would be best, but requires the overhead of creating classes and uses more memory. – sissonb Mar 08 '13 at 01:54
  • you are using `bitwise AND` (&). while returning. See [Operators in Java](http://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html) It has different meaning. You can declare `rolls` as an instance variable instead of local variable which will solve your problem where you need not to return two value. – AmitG Mar 09 '13 at 16:19

6 Answers6

13

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]
rgettman
  • 176,041
  • 30
  • 275
  • 357
  • What would I return a valueholder too? As in the statement: gameStatus=crapsGame(); what would hold the value of a value holder; if that makes any sense? Sorry if this sounds ridiculously idiotic... I'm completely unfamiliar with ValueHolder – Michael MacDonald Mar 08 '13 at 01:49
  • ValueHolder is a class that you will make -- a custom object. Then you'll write something like `ValueHolder valueHolder = crapsGame();` – rgettman Mar 08 '13 at 01:51
  • thank you! I went with the array method because it was slightly simpler (seeing as I only need two values) but i appreciate the reply and the merit of this method! Plus, I learned about something extra which is always nice; because I'd never heard of "ValueHolder"! – Michael MacDonald Mar 08 '13 at 02:01
5

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)
Francisco Meza
  • 875
  • 6
  • 8
  • I did end up going with the array method but I was wondering if you could expand a bit on the "return the bitwise and of gameStatus and rolls" What was I actually returning when I had it entered like that? – Michael MacDonald Mar 08 '13 at 02:06
  • @OscarWilde sure: the bitwise and operator & will apply a logic AND one bit at a time on its two operands (check this out: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html) – Francisco Meza Mar 19 '13 at 19:13
3

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

Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275
3

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.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
3

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)

katsos
  • 91
  • 3
  • 9
0

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");
    
Slava Vedenin
  • 58,326
  • 13
  • 40
  • 59