Java - Returning mixed data from a function

3.1k views Asked by At

I'm not new to programming but I am new to Java. I have an app with a function that needs to return an Integer and a Short value pulled from a database, so I can call the function, then use those two values elsewhere. I've tried a hashmap which I know can do this, but I don't want to iterate anything. It will always be a single "record" found, so one Int, and one Short.

What's the best method for this?

6

There are 6 answers

0
Oliver Charlesworth On BEST ANSWER

Define a helper class, and return that.

class MyResults {
    public final short a;
    public final int   b;
    public MyResults(short a, int b) { this.a = a; this.b = b; }
}


MyResults myMethod() {
    ...
    return new MyResults(42, 666);
}
0
Ryan Amos On

You should create a new object to do this. You can call it whatever you like: ShortIntPair, etc. Probably something more descriptive.

public class ShortIntPair {
    public short s;
    public int i;
    public ShortIntPair(int i, short s){
        this.i = i;
        this.s = s;
    }
}
0
JB Nizet On

Create a class containing these two properties, and return an instance of this class.

0
Mat On

Just return an object of class YourRecordType that has the two (possibly public) fields you need.

2
Adam Mihalcin On

A more general solution is to create a Pair<T1, T2> class, similar to the tuple construct in ML/OCaml/F# or the Tuple classes in C# but not quite as nice (not least because a general solution to this problem loses performance due to boxing/unboxing of primitives):

public final class Pair<T1, T2> {
    private final T1 item1;
    private final T2 item2;

    public Pair(T1 item1, T2 item2) {
        this.item1 = item1;
        this.item2 = item2;
    }

    public T1 getItem1() {
        return item1;
    }

    public T2 getItem2() {
        return item2;
    }
}

This class does have the benefit, though, that as long as T1 and T2 are immutable, objects of type Pair are also immutable.

0
Cameron Skinner On

Unfortunately Java doesn't support "out" parameters so there are only a few options, and they're all pretty mucky.

1) Have a struct-ish class for encapsulating the return type:

class MixedData {
    public int intValue;
    public short shortValue;
    public MixedData(int intValue, short shortValue) {...}
}

public MixedData foo() {
    return new MixedData(...);
}

2) Pass in a struct-ish (or object array, or whatever) as a fake "out" parameter

public void foo(MixedData result) {
    result.intValue = ...;
    result.shortValue = ...;
}

2.5) In your specific case you could actually abuse the java.util.concurrent.atomic package and do this:

public void foo(AtomicInteger intValue, AtomicInteger shortValue) {
    intValue.set(...);
    shortValue.set(...);
}

It gives you a much more C-like signature, but don't do it. Not least because there is no AtomicShort.

3) Return an array of objects and document which object is at each index:

/** 
 * @return intValue, shortValue
 */
public Object[] foo() {
    return new Object[] {intValue, shortValue};
}

Generally the "preferred" option is the first, but option 2 is good in some circumstances, too, especially if you are accumulating data over a series of methods. Passing arrays of objects around is nasty, but it'll work.

Of course you can also pass Maps or Collections around, too, if that makes sense for what you're doing.

There is something of a religious war over whether a general purpose Pair (or Tuple) class is a good idea or not; if it makes sense for your purposes then write a Pair class, if not then stick with a specific MixedData class.