Preamble: I am aware of using a list or other collections to return a result but then I have to go through the list plucking the results out: see 2nd example
Preambl
If you need to return multiple values of the same type, then a List or Set is appropriate. It is perfectly valid to return, for example, a variable-length username list as a List. If you know you are always going to return a fixed number of values, I would use an array. For example, in a method that returns a some kind of user ID as three distinct integers, I would use:
public int[] getUserId(){
int[] returnArray = new int[3];
returnArray[0] = getFirstPart();
returnArray[1] = getSecondPart();
returnArray[2] = getThirdPart();
return returnArray;
}
In the caller code, obtaining the values is as simple as array[0]
, array[1]
and array[2]
. This is much easier than a Collection, and you will not break anything, because user IDs are defined as being three integers.
If you really need to return multiple distinct values, then the holder class is the best option, no other way around that. Multiple return values are not supported in Java. But I would rather look at the solution from the design point of view. If a class needs to return multiple distinct values, then it probably does a lot of stuff, some of it unrelated to others. A single piece of code (a class, a method) should always have a single clear purpose and clearly defined responsibilities. Rather that returning multiple distinct values, I would consider splitting the method into multiple shorter method or define an inteface to externalise all the functionality. If those return values are related in any way and wouldn't have meaning if taken apart, then I think they deserve a class on their own.
You can have a method like with a signature like this :
List<Holder> foobar();
Can you return a List, Set, or Map?
You can use any of the Collection class for this purpose. This Lesson may help you in deciding what is best suited for you.
Returning an extended Holder seems better than returning a List:
class Holder {
int value1;
String value2;
Holder(int value1, String value2) {}
}
Holder foobar() {
return new Holder(1, "bar");
}
Using a generic tuple class is the closest I can imagine. To give an idea, such general purpose class for three return values could look something like this:
public class T3<A, B, C> {
A _1;
B _2;
C _3;
T3(A _1, B _2, C _3) {
this._1 = _1;
this._2 = _2;
this._3 = _3;
}
}
This allows a one statement constructor on the callee side, for example:
public T3<String, Integer, Character> getValues() {
return new T3<String, Integer, Character>("string", 0, 'c');
}
but no holder instance construction by the callee is to be done.
Each number of return values needs a tuple-class of its own. There might be something like that provided in the Functional Java library. For reference, here's an N-Tuple implementation.
For the two-valued case java.util.AbstractMap.SimpleEntry would do:
return new SimpleEntry<String, Integer>("string", 0);
Anyhow, I see two important points to consider for multiple return values:
As boring as it is, I'd recommend creating a separate class to hold all the response values and declare that as the method return type. That way the meaning of each value can be highlighted.