How do I use optional parameters in Java? - java

What specification supports optional parameters?

There are several ways to simulate optional parameters in Java:
Method overloading.
void foo(String a, Integer b) {
//...
}
void foo(String a) {
foo(a, 0); // here, 0 is a default value for b
}
foo("a", 2);
foo("a");
One of the limitations of this approach is that it doesn't work if you have two optional parameters of the same type and any of them can be omitted.
Varargs.
a) All optional parameters are of the same type:
void foo(String a, Integer... b) {
Integer b1 = b.length > 0 ? b[0] : 0;
Integer b2 = b.length > 1 ? b[1] : 0;
//...
}
foo("a");
foo("a", 1, 2);
b) Types of optional parameters may be different:
void foo(String a, Object... b) {
Integer b1 = 0;
String b2 = "";
if (b.length > 0) {
if (!(b[0] instanceof Integer)) {
throw new IllegalArgumentException("...");
}
b1 = (Integer)b[0];
}
if (b.length > 1) {
if (!(b[1] instanceof String)) {
throw new IllegalArgumentException("...");
}
b2 = (String)b[1];
//...
}
//...
}
foo("a");
foo("a", 1);
foo("a", 1, "b2");
The main drawback of this approach is that if optional parameters are of different types you lose static type checking. Furthermore, if each parameter has the different meaning you need some way to distinguish them.
Nulls. To address the limitations of the previous approaches you can allow null values and then analyze each parameter in a method body:
void foo(String a, Integer b, Integer c) {
b = b != null ? b : 0;
c = c != null ? c : 0;
//...
}
foo("a", null, 2);
Now all arguments values must be provided, but the default ones may be null.
Optional class. This approach is similar to nulls, but uses Java 8 Optional class for parameters that have a default value:
void foo(String a, Optional bOpt) {
Integer b = bOpt.isPresent() ? bOpt.get() : 0;
//...
}
foo("a", Optional.of(2));
foo("a", Optional.absent());
Optional makes a method contract explicit for a caller, however, one may find such signature too verbose.
Update: Java 8 includes the class java.util.Optional out-of-the-box, so there is no need to use guava for this particular reason in Java 8. The method name is a bit different though.
Builder pattern. The builder pattern is used for constructors and is implemented by introducing a separate Builder class:
class Foo {
private final String a;
private final Integer b;
Foo(String a, Integer b) {
this.a = a;
this.b = b;
}
//...
}
class FooBuilder {
private String a = "";
private Integer b = 0;
FooBuilder setA(String a) {
this.a = a;
return this;
}
FooBuilder setB(Integer b) {
this.b = b;
return this;
}
Foo build() {
return new Foo(a, b);
}
}
Foo foo = new FooBuilder().setA("a").build();
Maps. When the number of parameters is too large and for most of the default values are usually used, you can pass method arguments as a map of their names/values:
void foo(Map<String, Object> parameters) {
String a = "";
Integer b = 0;
if (parameters.containsKey("a")) {
if (!(parameters.get("a") instanceof Integer)) {
throw new IllegalArgumentException("...");
}
a = (Integer)parameters.get("a");
}
if (parameters.containsKey("b")) {
//...
}
//...
}
foo(ImmutableMap.<String, Object>of(
"a", "a",
"b", 2,
"d", "value"));
In Java 9, this approach became easier:
#SuppressWarnings("unchecked")
static <T> T getParm(Map<String, Object> map, String key, T defaultValue) {
return (map.containsKey(key)) ? (T) map.get(key) : defaultValue;
}
void foo(Map<String, Object> parameters) {
String a = getParm(parameters, "a", "");
int b = getParm(parameters, "b", 0);
// d = ...
}
foo(Map.of("a","a", "b",2, "d","value"));
Please note that you can combine any of these approaches to achieve a desirable result.

varargs could do that (in a way). Other than that, all variables in the declaration of the method must be supplied. If you want a variable to be optional, you can overload the method using a signature which doesn't require the parameter.
private boolean defaultOptionalFlagValue = true;
public void doSomething(boolean optionalFlag) {
...
}
public void doSomething() {
doSomething(defaultOptionalFlagValue);
}

There is optional parameters with Java 5.0. Just declare your function like this:
public void doSomething(boolean... optionalFlag) {
//default to "false"
//boolean flag = (optionalFlag.length >= 1) ? optionalFlag[0] : false;
}
you could call with doSomething(); or doSomething(true); now.

You can use something like this:
public void addError(String path, String key, Object... params) {
}
The params variable is optional. It is treated as a nullable array of Objects.
Strangely, I couldn't find anything about this in the documentation, but it works!
This is "new" in Java 1.5 and beyond (not supported in Java 1.4 or earlier).
I see user bhoot mentioned this too below.

There are no optional parameters in Java. What you can do is overloading the functions and then passing default values.
void SomeMethod(int age, String name) {
//
}
// Overload
void SomeMethod(int age) {
SomeMethod(age, "John Doe");
}

VarArgs and overloading have been mentioned. Another option is a Bloch Builder pattern, which would look something like this:
MyObject my = new MyObjectBuilder().setParam1(value)
.setParam3(otherValue)
.setParam6(thirdValue)
.build();
Although that pattern would be most appropriate for when you need optional parameters in a constructor.

In JDK>1.5 you can use it like this;
public class NewClass1 {
public static void main(String[] args) {
try {
someMethod(18); // Age : 18
someMethod(18, "John Doe"); // Age & Name : 18 & John Doe
} catch (Exception e) {
e.printStackTrace();
}
}
static void someMethod(int age, String... names) {
if (names.length > 0) {
if (names[0] != null) {
System.out.println("Age & Name : " + age + " & " + names[0]);
}
} else {
System.out.println("Age : " + age);
}
}
}

You can do thing using method overloading like this.
public void load(String name){ }
public void load(String name,int age){}
Also you can use #Nullable annotation
public void load(#Nullable String name,int age){}
simply pass null as first parameter.
If you are passing same type variable you can use this
public void load(String name...){}

Short version :
Using three dots:
public void foo(Object... x) {
String first = x.length > 0 ? (String)x[0] : "Hello";
int duration = x.length > 1 ? Integer.parseInt((String) x[1]) : 888;
}
foo("Hii", );
foo("Hii", 146);
(based on #VitaliiFedorenko's answer)

Overloading is fine, but if there's a lot of variables that needs default value, you will end up with :
public void methodA(A arg1) { }
public void methodA(B arg2) { }
public void methodA(C arg3) { }
public void methodA(A arg1, B arg2) { }
public void methodA(A arg1, C arg3) { }
public void methodA(B arg2, C arg3) { }
public void methodA(A arg1, B arg2, C arg3) { }
So I would suggest use the Variable Argument provided by Java.

You can use a class that works much like a builder to contain your optional values like this.
public class Options {
private String someString = "default value";
private int someInt= 0;
public Options setSomeString(String someString) {
this.someString = someString;
return this;
}
public Options setSomeInt(int someInt) {
this.someInt = someInt;
return this;
}
}
public static void foo(Consumer<Options> consumer) {
Options options = new Options();
consumer.accept(options);
System.out.println("someString = " + options.someString + ", someInt = " + options.someInt);
}
Use like
foo(o -> o.setSomeString("something").setSomeInt(5));
Output is
someString = something, someInt = 5
To skip all the optional values you'd have to call it like foo(o -> {}); or if you prefer, you can create a second foo() method that doesn't take the optional parameters.
Using this approach, you can specify optional values in any order without any ambiguity. You can also have parameters of different classes unlike with varargs. This approach would be even better if you can use annotations and code generation to create the Options class.

If it's an API endpoint, an elegant way is to use "Spring" annotations:
#GetMapping("/api/foos")
#ResponseBody
public String getFoos(#RequestParam(required = false, defaultValue = "hello") String id) {
return innerFunc(id);
}
Notice in this case that the innerFunc will require the variable, and since it's not api endpoint, can't use this Spring annotation to make it optional.
Reference: https://www.baeldung.com/spring-request-param

Java now supports optionals in 1.8, I'm stuck with programming on android so I'm using nulls until I can refactor the code to use optional types.
Object canBeNull() {
if (blah) {
return new Object();
} else {
return null;
}
}
Object optionalObject = canBeNull();
if (optionalObject != null) {
// new object returned
} else {
// no new object returned
}

This is an old question maybe even before actual Optional type was introduced but these days you can consider few things:
- use method overloading
- use Optional type which has advantage of avoiding passing NULLs around
Optional type was introduced in Java 8 before it was usually used from third party lib such as Google's Guava. Using optional as parameters / arguments can be consider as over-usage as the main purpose was to use it as a return time.
Ref: https://itcodehub.blogspot.com/2019/06/using-optional-type-in-java.html

Default arguments can not be used in Java. Where in C#, C++ and Python, we can use them..
In Java, we must have to use 2 methods (functions) instead of one with default parameters.
Example:
Stash(int size);
Stash(int size, int initQuantity);
http://parvindersingh.webs.com/apps/forums/topics/show/8856498-java-how-to-set-default-parameters-values-like-c-

We can make optional parameter by Method overloading or Using DataType...
|*| Method overloading :
RetDataType NameFnc(int NamePsgVar)
{
// |* Code Todo *|
return RetVar;
}
RetDataType NameFnc(String NamePsgVar)
{
// |* Code Todo *|
return RetVar;
}
RetDataType NameFnc(int NamePsgVar1, String NamePsgVar2)
{
// |* Code Todo *|
return RetVar;
}
Easiest way is
|*| DataType... can be optional parameter
RetDataType NameFnc(int NamePsgVar, String... stringOpnPsgVar)
{
if(stringOpnPsgVar.length == 0) stringOpnPsgVar = DefaultValue;
// |* Code Todo *|
return RetVar;
}

If you are planning to use an interface with multiple parameters,
one can use the following structural pattern and implement or override apply - a method based on your requirement.
public abstract class Invoker<T> {
public T apply() {
return apply(null);
}
public abstract T apply(Object... params);
}

Related

The primitive type double of sol1 does not have a field sol2 [duplicate]

I want to return two objects from a Java method and was wondering what could be a good way of doing so?
The possible ways I can think of are: return a HashMap (since the two Objects are related) or return an ArrayList of Object objects.
To be more precise, the two objects I want to return are (a) List of objects and (b) comma separated names of the same.
I want to return these two Objects from one method because I dont want to iterate through the list of objects to get the comma separated names (which I can do in the same loop in this method).
Somehow, returning a HashMap does not look a very elegant way of doing so.
If you want to return two objects you usually want to return a single object that encapsulates the two objects instead.
You could return a List of NamedObject objects like this:
public class NamedObject<T> {
public final String name;
public final T object;
public NamedObject(String name, T object) {
this.name = name;
this.object = object;
}
}
Then you can easily return a List<NamedObject<WhateverTypeYouWant>>.
Also: Why would you want to return a comma-separated list of names instead of a List<String>? Or better yet, return a Map<String,TheObjectType> with the keys being the names and the values the objects (unless your objects have specified order, in which case a NavigableMap might be what you want.
If you know you are going to return two objects, you can also use a generic pair:
public class Pair<A,B> {
public final A a;
public final B b;
public Pair(A a, B b) {
this.a = a;
this.b = b;
}
};
Edit A more fully formed implementation of the above:
package util;
public class Pair<A,B> {
public static <P, Q> Pair<P, Q> makePair(P p, Q q) {
return new Pair<P, Q>(p, q);
}
public final A a;
public final B b;
public Pair(A a, B b) {
this.a = a;
this.b = b;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((a == null) ? 0 : a.hashCode());
result = prime * result + ((b == null) ? 0 : b.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
#SuppressWarnings("rawtypes")
Pair other = (Pair) obj;
if (a == null) {
if (other.a != null) {
return false;
}
} else if (!a.equals(other.a)) {
return false;
}
if (b == null) {
if (other.b != null) {
return false;
}
} else if (!b.equals(other.b)) {
return false;
}
return true;
}
public boolean isInstance(Class<?> classA, Class<?> classB) {
return classA.isInstance(a) && classB.isInstance(b);
}
#SuppressWarnings("unchecked")
public static <P, Q> Pair<P, Q> cast(Pair<?, ?> pair, Class<P> pClass, Class<Q> qClass) {
if (pair.isInstance(pClass, qClass)) {
return (Pair<P, Q>) pair;
}
throw new ClassCastException();
}
}
Notes, mainly around rustiness with Java & generics:
both a and b are immutable.
makePair static method helps you with boiler plate typing, which the diamond operator in Java 7 will make less annoying. There's some work to make this really nice re: generics, but it should be ok-ish now. (c.f. PECS)
hashcode and equals are generated by eclipse.
the compile time casting in the cast method is ok, but doesn't seem quite right.
I'm not sure if the wildcards in isInstance are necessary.
I've just written this in response to comments, for illustration purposes only.
In the event the method you're calling is private, or called from one location, try
return new Object[]{value1, value2};
The caller looks like:
Object[] temp=myMethod(parameters);
Type1 value1=(Type1)temp[0]; //For code clarity: temp[0] is not descriptive
Type2 value2=(Type2)temp[1];
The Pair example by David Hanak has no syntactic benefit, and is limited to two values.
return new Pair<Type1,Type2>(value1, value2);
And the caller looks like:
Pair<Type1, Type2> temp=myMethod(parameters);
Type1 value1=temp.a; //For code clarity: temp.a is not descriptive
Type2 value2=temp.b;
You may use any of following ways:
private static final int RETURN_COUNT = 2;
private static final int VALUE_A = 0;
private static final int VALUE_B = 1;
private static final String A = "a";
private static final String B = "b";
1) Using Array
private static String[] methodWithArrayResult() {
//...
return new String[]{"valueA", "valueB"};
}
private static void usingArrayResultTest() {
String[] result = methodWithArrayResult();
System.out.println();
System.out.println("A = " + result[VALUE_A]);
System.out.println("B = " + result[VALUE_B]);
}
2) Using ArrayList
private static List<String> methodWithListResult() {
//...
return Arrays.asList("valueA", "valueB");
}
private static void usingListResultTest() {
List<String> result = methodWithListResult();
System.out.println();
System.out.println("A = " + result.get(VALUE_A));
System.out.println("B = " + result.get(VALUE_B));
}
3) Using HashMap
private static Map<String, String> methodWithMapResult() {
Map<String, String> result = new HashMap<>(RETURN_COUNT);
result.put(A, "valueA");
result.put(B, "valueB");
//...
return result;
}
private static void usingMapResultTest() {
Map<String, String> result = methodWithMapResult();
System.out.println();
System.out.println("A = " + result.get(A));
System.out.println("B = " + result.get(B));
}
4) Using your custom container class
private static class MyContainer<M,N> {
private final M first;
private final N second;
public MyContainer(M first, N second) {
this.first = first;
this.second = second;
}
public M getFirst() {
return first;
}
public N getSecond() {
return second;
}
// + hashcode, equals, toString if need
}
private static MyContainer<String, String> methodWithContainerResult() {
//...
return new MyContainer("valueA", "valueB");
}
private static void usingContainerResultTest() {
MyContainer<String, String> result = methodWithContainerResult();
System.out.println();
System.out.println("A = " + result.getFirst());
System.out.println("B = " + result.getSecond());
}
5) Using AbstractMap.simpleEntry
private static AbstractMap.SimpleEntry<String, String> methodWithAbstractMapSimpleEntryResult() {
//...
return new AbstractMap.SimpleEntry<>("valueA", "valueB");
}
private static void usingAbstractMapSimpleResultTest() {
AbstractMap.SimpleEntry<String, String> result = methodWithAbstractMapSimpleEntryResult();
System.out.println();
System.out.println("A = " + result.getKey());
System.out.println("B = " + result.getValue());
}
6) Using Pair of Apache Commons
private static Pair<String, String> methodWithPairResult() {
//...
return new ImmutablePair<>("valueA", "valueB");
}
private static void usingPairResultTest() {
Pair<String, String> result = methodWithPairResult();
System.out.println();
System.out.println("A = " + result.getKey());
System.out.println("B = " + result.getValue());
}
I almost always end up defining n-Tuple classes when I code in Java. For instance:
public class Tuple2<T1,T2> {
private T1 f1;
private T2 f2;
public Tuple2(T1 f1, T2 f2) {
this.f1 = f1; this.f2 = f2;
}
public T1 getF1() {return f1;}
public T2 getF2() {return f2;}
}
I know it's a bit ugly, but it works, and you just have to define your tuple types once. Tuples are something Java really lacks.
EDIT: David Hanak's example is more elegant, as it avoids defining getters and still keeps the object immutable.
Before Java 5, I would kind of agree that the Map solution isn't ideal. It wouldn't give you compile time type checking so can cause issues at runtime. However, with Java 5, we have Generic Types.
So your method could look like this:
public Map<String, MyType> doStuff();
MyType of course being the type of object you are returning.
Basically I think that returning a Map is the right solution in this case because that's exactly what you want to return - a mapping of a string to an object.
Apache Commons has tuple and triple for this:
ImmutablePair<L,R> An immutable pair consisting of two Object
elements.
ImmutableTriple<L,M,R> An immutable triple consisting of
three Object elements.
MutablePair<L,R> A mutable pair consisting of
two Object elements.
MutableTriple<L,M,R> A mutable triple
consisting of three Object elements.
Pair<L,R> A pair consisting of
two elements.
Triple<L,M,R> A triple consisting of three elements.
Source: https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/tuple/package-summary.html
Alternatively, in situations where I want to return a number of things from a method I will sometimes use a callback mechanism instead of a container. This works very well in situations where I cannot specify ahead of time just how many objects will be generated.
With your particular problem, it would look something like this:
public class ResultsConsumer implements ResultsGenerator.ResultsCallback
{
public void handleResult( String name, Object value )
{
...
}
}
public class ResultsGenerator
{
public interface ResultsCallback
{
void handleResult( String aName, Object aValue );
}
public void generateResults( ResultsGenerator.ResultsCallback aCallback )
{
Object value = null;
String name = null;
...
aCallback.handleResult( name, value );
}
}
While in your case, the comment may be a good way to go, in Android, you can use Pair . Simply
return new Pair<>(yourList, yourCommaSeparatedValues);
Use of following Entry object
Example :
public Entry<A,B> methodname(arg)
{
.......
return new AbstractMap.simpleEntry<A,B>(instanceOfA,instanceOfB);
}
Regarding the issue about multiple return values in general I usually use a small helper class that wraps a single return value and is passed as parameter to the method:
public class ReturnParameter<T> {
private T value;
public ReturnParameter() { this.value = null; }
public ReturnParameter(T initialValue) { this.value = initialValue; }
public void set(T value) { this.value = value; }
public T get() { return this.value; }
}
(for primitive datatypes I use minor variations to directly store the value)
A method that wants to return multiple values would then be declared as follows:
public void methodThatReturnsTwoValues(ReturnParameter<ClassA> nameForFirstValueToReturn, ReturnParameter<ClassB> nameForSecondValueToReturn) {
//...
nameForFirstValueToReturn.set("...");
nameForSecondValueToReturn.set("...");
//...
}
Maybe the major drawback is that the caller has to prepare the return objects in advance in case he wants to use them (and the method should check for null pointers)
ReturnParameter<ClassA> nameForFirstValue = new ReturnParameter<ClassA>();
ReturnParameter<ClassB> nameForSecondValue = new ReturnParameter<ClassB>();
methodThatReturnsTwoValues(nameForFirstValue, nameForSecondValue);
Advantages (in comparison to other solutions proposed):
You do not have to create a special class declaration for individual methods and its return types
The parameters get a name and therefore are easier to differentiate when looking at the method signature
Type safety for each parameter
All possible solutions will be a kludge (like container objects, your HashMap idea, “multiple return values” as realized via arrays). I recommend regenerating the comma-separated list from the returned List. The code will end up being a lot cleaner.
Keep it simple and create a class for multiple result situation. This example accepts an ArrayList and a message text from a databasehelper getInfo.
Where you call the routine that returns multiple values you code:
multResult res = mydb.getInfo();
In the routine getInfo you code:
ArrayList<String> list= new ArrayList<String>();
add values to the list...
return new multResult("the message", list);
and define a class multResult with:
public class multResult {
public String message; // or create a getter if you don't like public
public ArrayList<String> list;
multResult(String m, ArrayList<String> l){
message = m;
list= l;
}
}
As I see it there are really three choices here and the solution depends on the context. You can choose to implement the construction of the name in the method that produces the list. This is the choice you've chosen, but I don't think it is the best one. You are creating a coupling in the producer method to the consuming method that doesn't need to exist. Other callers may not need the extra information and you would be calculating extra information for these callers.
Alternatively, you could have the calling method calculate the name. If there is only one caller that needs this information, you can stop there. You have no extra dependencies and while there is a little extra calculation involved, you've avoided making your construction method too specific. This is a good trade-off.
Lastly, you could have the list itself be responsible for creating the name. This is the route I would go if the calculation needs to be done by more than one caller. I think this puts the responsibility for the creation of the names with the class that is most closely related to the objects themselves.
In the latter case, my solution would be to create a specialized List class that returns a comma-separated string of the names of objects that it contains. Make the class smart enough that it constructs the name string on the fly as objects are added and removed from it. Then return an instance of this list and call the name generation method as needed. Although it may be almost as efficient (and simpler) to simply delay calculation of the names until the first time the method is called and store it then (lazy loading). If you add/remove an object, you need only remove the calculated value and have it get recalculated on the next call.
Can do some thing like a tuple in dynamic language (Python)
public class Tuple {
private Object[] multiReturns;
private Tuple(Object... multiReturns) {
this.multiReturns = multiReturns;
}
public static Tuple _t(Object... multiReturns){
return new Tuple(multiReturns);
}
public <T> T at(int index, Class<T> someClass) {
return someClass.cast(multiReturns[index]);
}
}
and use like this
public Tuple returnMultiValues(){
return Tuple._t(new ArrayList(),new HashMap())
}
Tuple t = returnMultiValues();
ArrayList list = t.at(0,ArrayList.class);
I followed a similar approach than the described in the other answers with a few tweaks based on the requirement I had, basically I created the following classes(Just in case, everything is Java):
public class Pair<L, R> {
final L left;
final R right;
public Pair(L left, R right) {
this.left = left;
this.right = right;
}
public <T> T get(Class<T> param) {
return (T) (param == this.left.getClass() ? this.left : this.right);
}
public static <L, R> Pair<L, R> of(L left, R right) {
return new Pair<L, R>(left, right);
}
}
Then, my requirement was simple, in the repository Class that reaches the DB, for the Get Methods than retrieve data from the DB, I need to check if it failed or succeed, then, if succeed, I needed to play with the returning list, if failed, stop the execution and notify the error.
So, for example, my methods are like this:
public Pair<ResultMessage, List<Customer>> getCustomers() {
List<Customer> list = new ArrayList<Customer>();
try {
/*
* Do some work to get the list of Customers from the DB
* */
} catch (SQLException e) {
return Pair.of(
new ResultMessage(e.getErrorCode(), e.getMessage()), // Left
null); // Right
}
return Pair.of(
new ResultMessage(0, "SUCCESS"), // Left
list); // Right
}
Where ResultMessage is just a class with two fields (code/message) and Customer is any class with a bunch of fields that comes from the DB.
Then, to check the result I just do this:
void doSomething(){
Pair<ResultMessage, List<Customer>> customerResult = _repository.getCustomers();
if (customerResult.get(ResultMessage.class).getCode() == 0) {
List<Customer> listOfCustomers = customerResult.get(List.class);
System.out.println("do SOMETHING with the list ;) ");
}else {
System.out.println("Raised Error... do nothing!");
}
}
In C++ (STL) there is a pair class for bundling two objects. In Java Generics a pair class isn't available, although there is some demand for it. You could easily implement it yourself though.
I agree however with some other answers that if you need to return two or more objects from a method, it would be better to encapsulate them in a class.
Why not create a WhateverFunctionResult object that contains your results, and the logic required to parse these results, iterate over then etc. It seems to me that either:
These results objects are intimately tied together/related and belong together, or:
they are unrelated, in which case your function isn't well defined in terms of what it's trying to do (i.e. doing two different things)
I see this sort of issue crop up again and again. Don't be afraid to create your own container/result classes that contain the data and the associated functionality to handle this. If you simply pass the stuff around in a HashMap or similar, then your clients have to pull this map apart and grok the contents each time they want to use the results.
public class MultipleReturnValues {
public MultipleReturnValues() {
}
public static void functionWithSeveralReturnValues(final String[] returnValues) {
returnValues[0] = "return value 1";
returnValues[1] = "return value 2";
}
public static void main(String[] args) {
String[] returnValues = new String[2];
functionWithSeveralReturnValues(returnValues);
System.out.println("returnValues[0] = " + returnValues[0]);
System.out.println("returnValues[1] = " + returnValues[1]);
}
}
This is not exactly answering the question, but since every of the solution given here has some drawbacks, I suggest to try to refactor your code a little bit so you need to return only one value.
Case one.
You need something inside as well as outside of your method. Why not calculate it outside and pass it to the method?
Instead of:
[thingA, thingB] = createThings(...); // just a conceptual syntax of method returning two values, not valid in Java
Try:
thingA = createThingA(...);
thingB = createThingB(thingA, ...);
This should cover most of your needs, since in most situations one value is created before the other and you can split creating them in two methods. The drawback is that method createThingsB has an extra parameter comparing to createThings, and possibly you are passing exactly the same list of parameters twice to different methods.
Case two.
Most obvious solution ever and a simplified version of case one. It's not always possible, but maybe both of the values can be created independently of each other?
Instead of:
[thingA, thingB] = createThings(...); // see above
Try:
thingA = createThingA(...);
thingB = createThingB(...);
To make it more useful, these two methods can share some common logic:
public ThingA createThingA(...) {
doCommonThings(); // common logic
// create thing A
}
public ThingB createThingB(...) {
doCommonThings(); // common logic
// create thing B
}
Pass a list to your method and populate it, then return the String with the names, like this:
public String buildList(List<?> list) {
list.add(1);
list.add(2);
list.add(3);
return "something,something,something,dark side";
}
Then call it like this:
List<?> values = new ArrayList<?>();
String names = buildList(values);
You can utilize a HashMap<String, Object> as follows
public HashMap<String, Object> yourMethod()
{
.... different logic here
HashMap<String, Object> returnHashMap = new HashMap<String, Object>();
returnHashMap.put("objectA", objectAValue);
returnHashMap.put("myString", myStringValue);
returnHashMap.put("myBoolean", myBooleanValue);
return returnHashMap;
}
Then when calling the method in a different scope, you can cast each object back to its initial type:
// call the method
HashMap<String, Object> resultMap = yourMethod();
// fetch the results and cast them
ObjectA objectA = (ObjectA) resultMap.get("objectA");
String myString = (String) resultMap.get("myString");
Boolean myBoolean = (Boolean) resultMap.get("myBoolean");
I noticed there is no no-custom class, n-length, no-cast, type-safe answers yet to returning multiple values.
Here is my go:
import java.util.Objects;
public final class NTuple<V, T extends NTuple<?, ?>> {
private final V value;
private final T next;
private NTuple(V value, T next) {
this.value = value;
this.next = next;
}
public static <V> NTuple<V, ?> of(V value) {
return new NTuple<>(value, null);
}
public static <V, T extends NTuple<?, ?>> NTuple<V, T> of(V value, T next) {
return new NTuple<>(value, next);
}
public V value() {
return value;
}
public T next() {
return next;
}
public static <V> V unpack0(NTuple<V, ?> tuple) {
return Objects.requireNonNull(tuple, "0").value();
}
public static <V, T extends NTuple<V, ?>> V unpack1(NTuple<?, T> tuple) {
NTuple<?, T> tuple0 = Objects.requireNonNull(tuple, "0");
NTuple<V, ?> tuple1 = Objects.requireNonNull(tuple0.next(), "1");
return tuple1.value();
}
public static <V, T extends NTuple<?, NTuple<V, ?>>> V unpack2(NTuple<?, T> tuple) {
NTuple<?, T> tuple0 = Objects.requireNonNull(tuple, "0");
NTuple<?, NTuple<V, ?>> tuple1 = Objects.requireNonNull(tuple0.next(), "1");
NTuple<V, ?> tuple2 = Objects.requireNonNull(tuple1.next(), "2");
return tuple2.value();
}
}
Sample use:
public static void main(String[] args) {
// pre-java 10 without lombok - use lombok's var or java 10's var if you can
NTuple<String, NTuple<Integer, NTuple<Integer, ?>>> multiple = wordCount("hello world");
String original = NTuple.unpack0(multiple);
Integer wordCount = NTuple.unpack1(multiple);
Integer characterCount = NTuple.unpack2(multiple);
System.out.println(original + ": " + wordCount + " words " + characterCount + " chars");
}
private static NTuple<String, NTuple<Integer, NTuple<Integer, ?>>> wordCount(String s) {
int nWords = s.split(" ").length;
int nChars = s.length();
return NTuple.of(s, NTuple.of(nWords, NTuple.of(nChars)));
}
Pros:
no-custom container class - no need to write a class just for a return type
n-length - can handle any number of return values
no-cast - no need to cast from Object
type-safe - the types are checked via Java's generics
Cons:
inefficient for large numbers of return values
according to my experience with python's multiple return values, this should not happen in practice
heavy type declarations
can be alleviated by lombok/Java 10 var
In C, you would do it by passing pointers to placeholders for the results as arguments:
void getShoeAndWaistSizes(int *shoeSize, int *waistSize) {
*shoeSize = 36;
*waistSize = 45;
}
...
int shoeSize, waistSize;
getShoeAndWaistSize(&shoeSize, &waistSize);
int i = shoeSize + waistSize;
Let's try something similar, in Java.
void getShoeAndWaistSizes(List<Integer> shoeSize, List<Integer> waistSize) {
shoeSize.add(36);
waistSize.add(45);
}
...
List<Integer> shoeSize = new List<>();
List<Integer> waistSize = new List<>();
getShoeAndWaistSizes(shoeSize, waistSize);
int i = shoeSize.get(0) + waistSize.get(0);
PASS A HASH INTO THE METHOD AND POPULATE IT......
public void buildResponse(String data, Map response);

How to return two values from one method [duplicate]

I want to return two objects from a Java method and was wondering what could be a good way of doing so?
The possible ways I can think of are: return a HashMap (since the two Objects are related) or return an ArrayList of Object objects.
To be more precise, the two objects I want to return are (a) List of objects and (b) comma separated names of the same.
I want to return these two Objects from one method because I dont want to iterate through the list of objects to get the comma separated names (which I can do in the same loop in this method).
Somehow, returning a HashMap does not look a very elegant way of doing so.
If you want to return two objects you usually want to return a single object that encapsulates the two objects instead.
You could return a List of NamedObject objects like this:
public class NamedObject<T> {
public final String name;
public final T object;
public NamedObject(String name, T object) {
this.name = name;
this.object = object;
}
}
Then you can easily return a List<NamedObject<WhateverTypeYouWant>>.
Also: Why would you want to return a comma-separated list of names instead of a List<String>? Or better yet, return a Map<String,TheObjectType> with the keys being the names and the values the objects (unless your objects have specified order, in which case a NavigableMap might be what you want.
If you know you are going to return two objects, you can also use a generic pair:
public class Pair<A,B> {
public final A a;
public final B b;
public Pair(A a, B b) {
this.a = a;
this.b = b;
}
};
Edit A more fully formed implementation of the above:
package util;
public class Pair<A,B> {
public static <P, Q> Pair<P, Q> makePair(P p, Q q) {
return new Pair<P, Q>(p, q);
}
public final A a;
public final B b;
public Pair(A a, B b) {
this.a = a;
this.b = b;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((a == null) ? 0 : a.hashCode());
result = prime * result + ((b == null) ? 0 : b.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
#SuppressWarnings("rawtypes")
Pair other = (Pair) obj;
if (a == null) {
if (other.a != null) {
return false;
}
} else if (!a.equals(other.a)) {
return false;
}
if (b == null) {
if (other.b != null) {
return false;
}
} else if (!b.equals(other.b)) {
return false;
}
return true;
}
public boolean isInstance(Class<?> classA, Class<?> classB) {
return classA.isInstance(a) && classB.isInstance(b);
}
#SuppressWarnings("unchecked")
public static <P, Q> Pair<P, Q> cast(Pair<?, ?> pair, Class<P> pClass, Class<Q> qClass) {
if (pair.isInstance(pClass, qClass)) {
return (Pair<P, Q>) pair;
}
throw new ClassCastException();
}
}
Notes, mainly around rustiness with Java & generics:
both a and b are immutable.
makePair static method helps you with boiler plate typing, which the diamond operator in Java 7 will make less annoying. There's some work to make this really nice re: generics, but it should be ok-ish now. (c.f. PECS)
hashcode and equals are generated by eclipse.
the compile time casting in the cast method is ok, but doesn't seem quite right.
I'm not sure if the wildcards in isInstance are necessary.
I've just written this in response to comments, for illustration purposes only.
In the event the method you're calling is private, or called from one location, try
return new Object[]{value1, value2};
The caller looks like:
Object[] temp=myMethod(parameters);
Type1 value1=(Type1)temp[0]; //For code clarity: temp[0] is not descriptive
Type2 value2=(Type2)temp[1];
The Pair example by David Hanak has no syntactic benefit, and is limited to two values.
return new Pair<Type1,Type2>(value1, value2);
And the caller looks like:
Pair<Type1, Type2> temp=myMethod(parameters);
Type1 value1=temp.a; //For code clarity: temp.a is not descriptive
Type2 value2=temp.b;
You may use any of following ways:
private static final int RETURN_COUNT = 2;
private static final int VALUE_A = 0;
private static final int VALUE_B = 1;
private static final String A = "a";
private static final String B = "b";
1) Using Array
private static String[] methodWithArrayResult() {
//...
return new String[]{"valueA", "valueB"};
}
private static void usingArrayResultTest() {
String[] result = methodWithArrayResult();
System.out.println();
System.out.println("A = " + result[VALUE_A]);
System.out.println("B = " + result[VALUE_B]);
}
2) Using ArrayList
private static List<String> methodWithListResult() {
//...
return Arrays.asList("valueA", "valueB");
}
private static void usingListResultTest() {
List<String> result = methodWithListResult();
System.out.println();
System.out.println("A = " + result.get(VALUE_A));
System.out.println("B = " + result.get(VALUE_B));
}
3) Using HashMap
private static Map<String, String> methodWithMapResult() {
Map<String, String> result = new HashMap<>(RETURN_COUNT);
result.put(A, "valueA");
result.put(B, "valueB");
//...
return result;
}
private static void usingMapResultTest() {
Map<String, String> result = methodWithMapResult();
System.out.println();
System.out.println("A = " + result.get(A));
System.out.println("B = " + result.get(B));
}
4) Using your custom container class
private static class MyContainer<M,N> {
private final M first;
private final N second;
public MyContainer(M first, N second) {
this.first = first;
this.second = second;
}
public M getFirst() {
return first;
}
public N getSecond() {
return second;
}
// + hashcode, equals, toString if need
}
private static MyContainer<String, String> methodWithContainerResult() {
//...
return new MyContainer("valueA", "valueB");
}
private static void usingContainerResultTest() {
MyContainer<String, String> result = methodWithContainerResult();
System.out.println();
System.out.println("A = " + result.getFirst());
System.out.println("B = " + result.getSecond());
}
5) Using AbstractMap.simpleEntry
private static AbstractMap.SimpleEntry<String, String> methodWithAbstractMapSimpleEntryResult() {
//...
return new AbstractMap.SimpleEntry<>("valueA", "valueB");
}
private static void usingAbstractMapSimpleResultTest() {
AbstractMap.SimpleEntry<String, String> result = methodWithAbstractMapSimpleEntryResult();
System.out.println();
System.out.println("A = " + result.getKey());
System.out.println("B = " + result.getValue());
}
6) Using Pair of Apache Commons
private static Pair<String, String> methodWithPairResult() {
//...
return new ImmutablePair<>("valueA", "valueB");
}
private static void usingPairResultTest() {
Pair<String, String> result = methodWithPairResult();
System.out.println();
System.out.println("A = " + result.getKey());
System.out.println("B = " + result.getValue());
}
I almost always end up defining n-Tuple classes when I code in Java. For instance:
public class Tuple2<T1,T2> {
private T1 f1;
private T2 f2;
public Tuple2(T1 f1, T2 f2) {
this.f1 = f1; this.f2 = f2;
}
public T1 getF1() {return f1;}
public T2 getF2() {return f2;}
}
I know it's a bit ugly, but it works, and you just have to define your tuple types once. Tuples are something Java really lacks.
EDIT: David Hanak's example is more elegant, as it avoids defining getters and still keeps the object immutable.
Before Java 5, I would kind of agree that the Map solution isn't ideal. It wouldn't give you compile time type checking so can cause issues at runtime. However, with Java 5, we have Generic Types.
So your method could look like this:
public Map<String, MyType> doStuff();
MyType of course being the type of object you are returning.
Basically I think that returning a Map is the right solution in this case because that's exactly what you want to return - a mapping of a string to an object.
Apache Commons has tuple and triple for this:
ImmutablePair<L,R> An immutable pair consisting of two Object
elements.
ImmutableTriple<L,M,R> An immutable triple consisting of
three Object elements.
MutablePair<L,R> A mutable pair consisting of
two Object elements.
MutableTriple<L,M,R> A mutable triple
consisting of three Object elements.
Pair<L,R> A pair consisting of
two elements.
Triple<L,M,R> A triple consisting of three elements.
Source: https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/tuple/package-summary.html
Alternatively, in situations where I want to return a number of things from a method I will sometimes use a callback mechanism instead of a container. This works very well in situations where I cannot specify ahead of time just how many objects will be generated.
With your particular problem, it would look something like this:
public class ResultsConsumer implements ResultsGenerator.ResultsCallback
{
public void handleResult( String name, Object value )
{
...
}
}
public class ResultsGenerator
{
public interface ResultsCallback
{
void handleResult( String aName, Object aValue );
}
public void generateResults( ResultsGenerator.ResultsCallback aCallback )
{
Object value = null;
String name = null;
...
aCallback.handleResult( name, value );
}
}
While in your case, the comment may be a good way to go, in Android, you can use Pair . Simply
return new Pair<>(yourList, yourCommaSeparatedValues);
Use of following Entry object
Example :
public Entry<A,B> methodname(arg)
{
.......
return new AbstractMap.simpleEntry<A,B>(instanceOfA,instanceOfB);
}
Regarding the issue about multiple return values in general I usually use a small helper class that wraps a single return value and is passed as parameter to the method:
public class ReturnParameter<T> {
private T value;
public ReturnParameter() { this.value = null; }
public ReturnParameter(T initialValue) { this.value = initialValue; }
public void set(T value) { this.value = value; }
public T get() { return this.value; }
}
(for primitive datatypes I use minor variations to directly store the value)
A method that wants to return multiple values would then be declared as follows:
public void methodThatReturnsTwoValues(ReturnParameter<ClassA> nameForFirstValueToReturn, ReturnParameter<ClassB> nameForSecondValueToReturn) {
//...
nameForFirstValueToReturn.set("...");
nameForSecondValueToReturn.set("...");
//...
}
Maybe the major drawback is that the caller has to prepare the return objects in advance in case he wants to use them (and the method should check for null pointers)
ReturnParameter<ClassA> nameForFirstValue = new ReturnParameter<ClassA>();
ReturnParameter<ClassB> nameForSecondValue = new ReturnParameter<ClassB>();
methodThatReturnsTwoValues(nameForFirstValue, nameForSecondValue);
Advantages (in comparison to other solutions proposed):
You do not have to create a special class declaration for individual methods and its return types
The parameters get a name and therefore are easier to differentiate when looking at the method signature
Type safety for each parameter
All possible solutions will be a kludge (like container objects, your HashMap idea, “multiple return values” as realized via arrays). I recommend regenerating the comma-separated list from the returned List. The code will end up being a lot cleaner.
Keep it simple and create a class for multiple result situation. This example accepts an ArrayList and a message text from a databasehelper getInfo.
Where you call the routine that returns multiple values you code:
multResult res = mydb.getInfo();
In the routine getInfo you code:
ArrayList<String> list= new ArrayList<String>();
add values to the list...
return new multResult("the message", list);
and define a class multResult with:
public class multResult {
public String message; // or create a getter if you don't like public
public ArrayList<String> list;
multResult(String m, ArrayList<String> l){
message = m;
list= l;
}
}
As I see it there are really three choices here and the solution depends on the context. You can choose to implement the construction of the name in the method that produces the list. This is the choice you've chosen, but I don't think it is the best one. You are creating a coupling in the producer method to the consuming method that doesn't need to exist. Other callers may not need the extra information and you would be calculating extra information for these callers.
Alternatively, you could have the calling method calculate the name. If there is only one caller that needs this information, you can stop there. You have no extra dependencies and while there is a little extra calculation involved, you've avoided making your construction method too specific. This is a good trade-off.
Lastly, you could have the list itself be responsible for creating the name. This is the route I would go if the calculation needs to be done by more than one caller. I think this puts the responsibility for the creation of the names with the class that is most closely related to the objects themselves.
In the latter case, my solution would be to create a specialized List class that returns a comma-separated string of the names of objects that it contains. Make the class smart enough that it constructs the name string on the fly as objects are added and removed from it. Then return an instance of this list and call the name generation method as needed. Although it may be almost as efficient (and simpler) to simply delay calculation of the names until the first time the method is called and store it then (lazy loading). If you add/remove an object, you need only remove the calculated value and have it get recalculated on the next call.
Can do some thing like a tuple in dynamic language (Python)
public class Tuple {
private Object[] multiReturns;
private Tuple(Object... multiReturns) {
this.multiReturns = multiReturns;
}
public static Tuple _t(Object... multiReturns){
return new Tuple(multiReturns);
}
public <T> T at(int index, Class<T> someClass) {
return someClass.cast(multiReturns[index]);
}
}
and use like this
public Tuple returnMultiValues(){
return Tuple._t(new ArrayList(),new HashMap())
}
Tuple t = returnMultiValues();
ArrayList list = t.at(0,ArrayList.class);
I followed a similar approach than the described in the other answers with a few tweaks based on the requirement I had, basically I created the following classes(Just in case, everything is Java):
public class Pair<L, R> {
final L left;
final R right;
public Pair(L left, R right) {
this.left = left;
this.right = right;
}
public <T> T get(Class<T> param) {
return (T) (param == this.left.getClass() ? this.left : this.right);
}
public static <L, R> Pair<L, R> of(L left, R right) {
return new Pair<L, R>(left, right);
}
}
Then, my requirement was simple, in the repository Class that reaches the DB, for the Get Methods than retrieve data from the DB, I need to check if it failed or succeed, then, if succeed, I needed to play with the returning list, if failed, stop the execution and notify the error.
So, for example, my methods are like this:
public Pair<ResultMessage, List<Customer>> getCustomers() {
List<Customer> list = new ArrayList<Customer>();
try {
/*
* Do some work to get the list of Customers from the DB
* */
} catch (SQLException e) {
return Pair.of(
new ResultMessage(e.getErrorCode(), e.getMessage()), // Left
null); // Right
}
return Pair.of(
new ResultMessage(0, "SUCCESS"), // Left
list); // Right
}
Where ResultMessage is just a class with two fields (code/message) and Customer is any class with a bunch of fields that comes from the DB.
Then, to check the result I just do this:
void doSomething(){
Pair<ResultMessage, List<Customer>> customerResult = _repository.getCustomers();
if (customerResult.get(ResultMessage.class).getCode() == 0) {
List<Customer> listOfCustomers = customerResult.get(List.class);
System.out.println("do SOMETHING with the list ;) ");
}else {
System.out.println("Raised Error... do nothing!");
}
}
In C++ (STL) there is a pair class for bundling two objects. In Java Generics a pair class isn't available, although there is some demand for it. You could easily implement it yourself though.
I agree however with some other answers that if you need to return two or more objects from a method, it would be better to encapsulate them in a class.
Why not create a WhateverFunctionResult object that contains your results, and the logic required to parse these results, iterate over then etc. It seems to me that either:
These results objects are intimately tied together/related and belong together, or:
they are unrelated, in which case your function isn't well defined in terms of what it's trying to do (i.e. doing two different things)
I see this sort of issue crop up again and again. Don't be afraid to create your own container/result classes that contain the data and the associated functionality to handle this. If you simply pass the stuff around in a HashMap or similar, then your clients have to pull this map apart and grok the contents each time they want to use the results.
public class MultipleReturnValues {
public MultipleReturnValues() {
}
public static void functionWithSeveralReturnValues(final String[] returnValues) {
returnValues[0] = "return value 1";
returnValues[1] = "return value 2";
}
public static void main(String[] args) {
String[] returnValues = new String[2];
functionWithSeveralReturnValues(returnValues);
System.out.println("returnValues[0] = " + returnValues[0]);
System.out.println("returnValues[1] = " + returnValues[1]);
}
}
This is not exactly answering the question, but since every of the solution given here has some drawbacks, I suggest to try to refactor your code a little bit so you need to return only one value.
Case one.
You need something inside as well as outside of your method. Why not calculate it outside and pass it to the method?
Instead of:
[thingA, thingB] = createThings(...); // just a conceptual syntax of method returning two values, not valid in Java
Try:
thingA = createThingA(...);
thingB = createThingB(thingA, ...);
This should cover most of your needs, since in most situations one value is created before the other and you can split creating them in two methods. The drawback is that method createThingsB has an extra parameter comparing to createThings, and possibly you are passing exactly the same list of parameters twice to different methods.
Case two.
Most obvious solution ever and a simplified version of case one. It's not always possible, but maybe both of the values can be created independently of each other?
Instead of:
[thingA, thingB] = createThings(...); // see above
Try:
thingA = createThingA(...);
thingB = createThingB(...);
To make it more useful, these two methods can share some common logic:
public ThingA createThingA(...) {
doCommonThings(); // common logic
// create thing A
}
public ThingB createThingB(...) {
doCommonThings(); // common logic
// create thing B
}
Pass a list to your method and populate it, then return the String with the names, like this:
public String buildList(List<?> list) {
list.add(1);
list.add(2);
list.add(3);
return "something,something,something,dark side";
}
Then call it like this:
List<?> values = new ArrayList<?>();
String names = buildList(values);
You can utilize a HashMap<String, Object> as follows
public HashMap<String, Object> yourMethod()
{
.... different logic here
HashMap<String, Object> returnHashMap = new HashMap<String, Object>();
returnHashMap.put("objectA", objectAValue);
returnHashMap.put("myString", myStringValue);
returnHashMap.put("myBoolean", myBooleanValue);
return returnHashMap;
}
Then when calling the method in a different scope, you can cast each object back to its initial type:
// call the method
HashMap<String, Object> resultMap = yourMethod();
// fetch the results and cast them
ObjectA objectA = (ObjectA) resultMap.get("objectA");
String myString = (String) resultMap.get("myString");
Boolean myBoolean = (Boolean) resultMap.get("myBoolean");
I noticed there is no no-custom class, n-length, no-cast, type-safe answers yet to returning multiple values.
Here is my go:
import java.util.Objects;
public final class NTuple<V, T extends NTuple<?, ?>> {
private final V value;
private final T next;
private NTuple(V value, T next) {
this.value = value;
this.next = next;
}
public static <V> NTuple<V, ?> of(V value) {
return new NTuple<>(value, null);
}
public static <V, T extends NTuple<?, ?>> NTuple<V, T> of(V value, T next) {
return new NTuple<>(value, next);
}
public V value() {
return value;
}
public T next() {
return next;
}
public static <V> V unpack0(NTuple<V, ?> tuple) {
return Objects.requireNonNull(tuple, "0").value();
}
public static <V, T extends NTuple<V, ?>> V unpack1(NTuple<?, T> tuple) {
NTuple<?, T> tuple0 = Objects.requireNonNull(tuple, "0");
NTuple<V, ?> tuple1 = Objects.requireNonNull(tuple0.next(), "1");
return tuple1.value();
}
public static <V, T extends NTuple<?, NTuple<V, ?>>> V unpack2(NTuple<?, T> tuple) {
NTuple<?, T> tuple0 = Objects.requireNonNull(tuple, "0");
NTuple<?, NTuple<V, ?>> tuple1 = Objects.requireNonNull(tuple0.next(), "1");
NTuple<V, ?> tuple2 = Objects.requireNonNull(tuple1.next(), "2");
return tuple2.value();
}
}
Sample use:
public static void main(String[] args) {
// pre-java 10 without lombok - use lombok's var or java 10's var if you can
NTuple<String, NTuple<Integer, NTuple<Integer, ?>>> multiple = wordCount("hello world");
String original = NTuple.unpack0(multiple);
Integer wordCount = NTuple.unpack1(multiple);
Integer characterCount = NTuple.unpack2(multiple);
System.out.println(original + ": " + wordCount + " words " + characterCount + " chars");
}
private static NTuple<String, NTuple<Integer, NTuple<Integer, ?>>> wordCount(String s) {
int nWords = s.split(" ").length;
int nChars = s.length();
return NTuple.of(s, NTuple.of(nWords, NTuple.of(nChars)));
}
Pros:
no-custom container class - no need to write a class just for a return type
n-length - can handle any number of return values
no-cast - no need to cast from Object
type-safe - the types are checked via Java's generics
Cons:
inefficient for large numbers of return values
according to my experience with python's multiple return values, this should not happen in practice
heavy type declarations
can be alleviated by lombok/Java 10 var
In C, you would do it by passing pointers to placeholders for the results as arguments:
void getShoeAndWaistSizes(int *shoeSize, int *waistSize) {
*shoeSize = 36;
*waistSize = 45;
}
...
int shoeSize, waistSize;
getShoeAndWaistSize(&shoeSize, &waistSize);
int i = shoeSize + waistSize;
Let's try something similar, in Java.
void getShoeAndWaistSizes(List<Integer> shoeSize, List<Integer> waistSize) {
shoeSize.add(36);
waistSize.add(45);
}
...
List<Integer> shoeSize = new List<>();
List<Integer> waistSize = new List<>();
getShoeAndWaistSizes(shoeSize, waistSize);
int i = shoeSize.get(0) + waistSize.get(0);
PASS A HASH INTO THE METHOD AND POPULATE IT......
public void buildResponse(String data, Map response);

How to return 2 objects from a method [duplicate]

I want to return two objects from a Java method and was wondering what could be a good way of doing so?
The possible ways I can think of are: return a HashMap (since the two Objects are related) or return an ArrayList of Object objects.
To be more precise, the two objects I want to return are (a) List of objects and (b) comma separated names of the same.
I want to return these two Objects from one method because I dont want to iterate through the list of objects to get the comma separated names (which I can do in the same loop in this method).
Somehow, returning a HashMap does not look a very elegant way of doing so.
If you want to return two objects you usually want to return a single object that encapsulates the two objects instead.
You could return a List of NamedObject objects like this:
public class NamedObject<T> {
public final String name;
public final T object;
public NamedObject(String name, T object) {
this.name = name;
this.object = object;
}
}
Then you can easily return a List<NamedObject<WhateverTypeYouWant>>.
Also: Why would you want to return a comma-separated list of names instead of a List<String>? Or better yet, return a Map<String,TheObjectType> with the keys being the names and the values the objects (unless your objects have specified order, in which case a NavigableMap might be what you want.
If you know you are going to return two objects, you can also use a generic pair:
public class Pair<A,B> {
public final A a;
public final B b;
public Pair(A a, B b) {
this.a = a;
this.b = b;
}
};
Edit A more fully formed implementation of the above:
package util;
public class Pair<A,B> {
public static <P, Q> Pair<P, Q> makePair(P p, Q q) {
return new Pair<P, Q>(p, q);
}
public final A a;
public final B b;
public Pair(A a, B b) {
this.a = a;
this.b = b;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((a == null) ? 0 : a.hashCode());
result = prime * result + ((b == null) ? 0 : b.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
#SuppressWarnings("rawtypes")
Pair other = (Pair) obj;
if (a == null) {
if (other.a != null) {
return false;
}
} else if (!a.equals(other.a)) {
return false;
}
if (b == null) {
if (other.b != null) {
return false;
}
} else if (!b.equals(other.b)) {
return false;
}
return true;
}
public boolean isInstance(Class<?> classA, Class<?> classB) {
return classA.isInstance(a) && classB.isInstance(b);
}
#SuppressWarnings("unchecked")
public static <P, Q> Pair<P, Q> cast(Pair<?, ?> pair, Class<P> pClass, Class<Q> qClass) {
if (pair.isInstance(pClass, qClass)) {
return (Pair<P, Q>) pair;
}
throw new ClassCastException();
}
}
Notes, mainly around rustiness with Java & generics:
both a and b are immutable.
makePair static method helps you with boiler plate typing, which the diamond operator in Java 7 will make less annoying. There's some work to make this really nice re: generics, but it should be ok-ish now. (c.f. PECS)
hashcode and equals are generated by eclipse.
the compile time casting in the cast method is ok, but doesn't seem quite right.
I'm not sure if the wildcards in isInstance are necessary.
I've just written this in response to comments, for illustration purposes only.
In the event the method you're calling is private, or called from one location, try
return new Object[]{value1, value2};
The caller looks like:
Object[] temp=myMethod(parameters);
Type1 value1=(Type1)temp[0]; //For code clarity: temp[0] is not descriptive
Type2 value2=(Type2)temp[1];
The Pair example by David Hanak has no syntactic benefit, and is limited to two values.
return new Pair<Type1,Type2>(value1, value2);
And the caller looks like:
Pair<Type1, Type2> temp=myMethod(parameters);
Type1 value1=temp.a; //For code clarity: temp.a is not descriptive
Type2 value2=temp.b;
You may use any of following ways:
private static final int RETURN_COUNT = 2;
private static final int VALUE_A = 0;
private static final int VALUE_B = 1;
private static final String A = "a";
private static final String B = "b";
1) Using Array
private static String[] methodWithArrayResult() {
//...
return new String[]{"valueA", "valueB"};
}
private static void usingArrayResultTest() {
String[] result = methodWithArrayResult();
System.out.println();
System.out.println("A = " + result[VALUE_A]);
System.out.println("B = " + result[VALUE_B]);
}
2) Using ArrayList
private static List<String> methodWithListResult() {
//...
return Arrays.asList("valueA", "valueB");
}
private static void usingListResultTest() {
List<String> result = methodWithListResult();
System.out.println();
System.out.println("A = " + result.get(VALUE_A));
System.out.println("B = " + result.get(VALUE_B));
}
3) Using HashMap
private static Map<String, String> methodWithMapResult() {
Map<String, String> result = new HashMap<>(RETURN_COUNT);
result.put(A, "valueA");
result.put(B, "valueB");
//...
return result;
}
private static void usingMapResultTest() {
Map<String, String> result = methodWithMapResult();
System.out.println();
System.out.println("A = " + result.get(A));
System.out.println("B = " + result.get(B));
}
4) Using your custom container class
private static class MyContainer<M,N> {
private final M first;
private final N second;
public MyContainer(M first, N second) {
this.first = first;
this.second = second;
}
public M getFirst() {
return first;
}
public N getSecond() {
return second;
}
// + hashcode, equals, toString if need
}
private static MyContainer<String, String> methodWithContainerResult() {
//...
return new MyContainer("valueA", "valueB");
}
private static void usingContainerResultTest() {
MyContainer<String, String> result = methodWithContainerResult();
System.out.println();
System.out.println("A = " + result.getFirst());
System.out.println("B = " + result.getSecond());
}
5) Using AbstractMap.simpleEntry
private static AbstractMap.SimpleEntry<String, String> methodWithAbstractMapSimpleEntryResult() {
//...
return new AbstractMap.SimpleEntry<>("valueA", "valueB");
}
private static void usingAbstractMapSimpleResultTest() {
AbstractMap.SimpleEntry<String, String> result = methodWithAbstractMapSimpleEntryResult();
System.out.println();
System.out.println("A = " + result.getKey());
System.out.println("B = " + result.getValue());
}
6) Using Pair of Apache Commons
private static Pair<String, String> methodWithPairResult() {
//...
return new ImmutablePair<>("valueA", "valueB");
}
private static void usingPairResultTest() {
Pair<String, String> result = methodWithPairResult();
System.out.println();
System.out.println("A = " + result.getKey());
System.out.println("B = " + result.getValue());
}
I almost always end up defining n-Tuple classes when I code in Java. For instance:
public class Tuple2<T1,T2> {
private T1 f1;
private T2 f2;
public Tuple2(T1 f1, T2 f2) {
this.f1 = f1; this.f2 = f2;
}
public T1 getF1() {return f1;}
public T2 getF2() {return f2;}
}
I know it's a bit ugly, but it works, and you just have to define your tuple types once. Tuples are something Java really lacks.
EDIT: David Hanak's example is more elegant, as it avoids defining getters and still keeps the object immutable.
Before Java 5, I would kind of agree that the Map solution isn't ideal. It wouldn't give you compile time type checking so can cause issues at runtime. However, with Java 5, we have Generic Types.
So your method could look like this:
public Map<String, MyType> doStuff();
MyType of course being the type of object you are returning.
Basically I think that returning a Map is the right solution in this case because that's exactly what you want to return - a mapping of a string to an object.
Apache Commons has tuple and triple for this:
ImmutablePair<L,R> An immutable pair consisting of two Object
elements.
ImmutableTriple<L,M,R> An immutable triple consisting of
three Object elements.
MutablePair<L,R> A mutable pair consisting of
two Object elements.
MutableTriple<L,M,R> A mutable triple
consisting of three Object elements.
Pair<L,R> A pair consisting of
two elements.
Triple<L,M,R> A triple consisting of three elements.
Source: https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/tuple/package-summary.html
Alternatively, in situations where I want to return a number of things from a method I will sometimes use a callback mechanism instead of a container. This works very well in situations where I cannot specify ahead of time just how many objects will be generated.
With your particular problem, it would look something like this:
public class ResultsConsumer implements ResultsGenerator.ResultsCallback
{
public void handleResult( String name, Object value )
{
...
}
}
public class ResultsGenerator
{
public interface ResultsCallback
{
void handleResult( String aName, Object aValue );
}
public void generateResults( ResultsGenerator.ResultsCallback aCallback )
{
Object value = null;
String name = null;
...
aCallback.handleResult( name, value );
}
}
While in your case, the comment may be a good way to go, in Android, you can use Pair . Simply
return new Pair<>(yourList, yourCommaSeparatedValues);
Use of following Entry object
Example :
public Entry<A,B> methodname(arg)
{
.......
return new AbstractMap.simpleEntry<A,B>(instanceOfA,instanceOfB);
}
Regarding the issue about multiple return values in general I usually use a small helper class that wraps a single return value and is passed as parameter to the method:
public class ReturnParameter<T> {
private T value;
public ReturnParameter() { this.value = null; }
public ReturnParameter(T initialValue) { this.value = initialValue; }
public void set(T value) { this.value = value; }
public T get() { return this.value; }
}
(for primitive datatypes I use minor variations to directly store the value)
A method that wants to return multiple values would then be declared as follows:
public void methodThatReturnsTwoValues(ReturnParameter<ClassA> nameForFirstValueToReturn, ReturnParameter<ClassB> nameForSecondValueToReturn) {
//...
nameForFirstValueToReturn.set("...");
nameForSecondValueToReturn.set("...");
//...
}
Maybe the major drawback is that the caller has to prepare the return objects in advance in case he wants to use them (and the method should check for null pointers)
ReturnParameter<ClassA> nameForFirstValue = new ReturnParameter<ClassA>();
ReturnParameter<ClassB> nameForSecondValue = new ReturnParameter<ClassB>();
methodThatReturnsTwoValues(nameForFirstValue, nameForSecondValue);
Advantages (in comparison to other solutions proposed):
You do not have to create a special class declaration for individual methods and its return types
The parameters get a name and therefore are easier to differentiate when looking at the method signature
Type safety for each parameter
All possible solutions will be a kludge (like container objects, your HashMap idea, “multiple return values” as realized via arrays). I recommend regenerating the comma-separated list from the returned List. The code will end up being a lot cleaner.
Keep it simple and create a class for multiple result situation. This example accepts an ArrayList and a message text from a databasehelper getInfo.
Where you call the routine that returns multiple values you code:
multResult res = mydb.getInfo();
In the routine getInfo you code:
ArrayList<String> list= new ArrayList<String>();
add values to the list...
return new multResult("the message", list);
and define a class multResult with:
public class multResult {
public String message; // or create a getter if you don't like public
public ArrayList<String> list;
multResult(String m, ArrayList<String> l){
message = m;
list= l;
}
}
As I see it there are really three choices here and the solution depends on the context. You can choose to implement the construction of the name in the method that produces the list. This is the choice you've chosen, but I don't think it is the best one. You are creating a coupling in the producer method to the consuming method that doesn't need to exist. Other callers may not need the extra information and you would be calculating extra information for these callers.
Alternatively, you could have the calling method calculate the name. If there is only one caller that needs this information, you can stop there. You have no extra dependencies and while there is a little extra calculation involved, you've avoided making your construction method too specific. This is a good trade-off.
Lastly, you could have the list itself be responsible for creating the name. This is the route I would go if the calculation needs to be done by more than one caller. I think this puts the responsibility for the creation of the names with the class that is most closely related to the objects themselves.
In the latter case, my solution would be to create a specialized List class that returns a comma-separated string of the names of objects that it contains. Make the class smart enough that it constructs the name string on the fly as objects are added and removed from it. Then return an instance of this list and call the name generation method as needed. Although it may be almost as efficient (and simpler) to simply delay calculation of the names until the first time the method is called and store it then (lazy loading). If you add/remove an object, you need only remove the calculated value and have it get recalculated on the next call.
Can do some thing like a tuple in dynamic language (Python)
public class Tuple {
private Object[] multiReturns;
private Tuple(Object... multiReturns) {
this.multiReturns = multiReturns;
}
public static Tuple _t(Object... multiReturns){
return new Tuple(multiReturns);
}
public <T> T at(int index, Class<T> someClass) {
return someClass.cast(multiReturns[index]);
}
}
and use like this
public Tuple returnMultiValues(){
return Tuple._t(new ArrayList(),new HashMap())
}
Tuple t = returnMultiValues();
ArrayList list = t.at(0,ArrayList.class);
I followed a similar approach than the described in the other answers with a few tweaks based on the requirement I had, basically I created the following classes(Just in case, everything is Java):
public class Pair<L, R> {
final L left;
final R right;
public Pair(L left, R right) {
this.left = left;
this.right = right;
}
public <T> T get(Class<T> param) {
return (T) (param == this.left.getClass() ? this.left : this.right);
}
public static <L, R> Pair<L, R> of(L left, R right) {
return new Pair<L, R>(left, right);
}
}
Then, my requirement was simple, in the repository Class that reaches the DB, for the Get Methods than retrieve data from the DB, I need to check if it failed or succeed, then, if succeed, I needed to play with the returning list, if failed, stop the execution and notify the error.
So, for example, my methods are like this:
public Pair<ResultMessage, List<Customer>> getCustomers() {
List<Customer> list = new ArrayList<Customer>();
try {
/*
* Do some work to get the list of Customers from the DB
* */
} catch (SQLException e) {
return Pair.of(
new ResultMessage(e.getErrorCode(), e.getMessage()), // Left
null); // Right
}
return Pair.of(
new ResultMessage(0, "SUCCESS"), // Left
list); // Right
}
Where ResultMessage is just a class with two fields (code/message) and Customer is any class with a bunch of fields that comes from the DB.
Then, to check the result I just do this:
void doSomething(){
Pair<ResultMessage, List<Customer>> customerResult = _repository.getCustomers();
if (customerResult.get(ResultMessage.class).getCode() == 0) {
List<Customer> listOfCustomers = customerResult.get(List.class);
System.out.println("do SOMETHING with the list ;) ");
}else {
System.out.println("Raised Error... do nothing!");
}
}
In C++ (STL) there is a pair class for bundling two objects. In Java Generics a pair class isn't available, although there is some demand for it. You could easily implement it yourself though.
I agree however with some other answers that if you need to return two or more objects from a method, it would be better to encapsulate them in a class.
Why not create a WhateverFunctionResult object that contains your results, and the logic required to parse these results, iterate over then etc. It seems to me that either:
These results objects are intimately tied together/related and belong together, or:
they are unrelated, in which case your function isn't well defined in terms of what it's trying to do (i.e. doing two different things)
I see this sort of issue crop up again and again. Don't be afraid to create your own container/result classes that contain the data and the associated functionality to handle this. If you simply pass the stuff around in a HashMap or similar, then your clients have to pull this map apart and grok the contents each time they want to use the results.
public class MultipleReturnValues {
public MultipleReturnValues() {
}
public static void functionWithSeveralReturnValues(final String[] returnValues) {
returnValues[0] = "return value 1";
returnValues[1] = "return value 2";
}
public static void main(String[] args) {
String[] returnValues = new String[2];
functionWithSeveralReturnValues(returnValues);
System.out.println("returnValues[0] = " + returnValues[0]);
System.out.println("returnValues[1] = " + returnValues[1]);
}
}
This is not exactly answering the question, but since every of the solution given here has some drawbacks, I suggest to try to refactor your code a little bit so you need to return only one value.
Case one.
You need something inside as well as outside of your method. Why not calculate it outside and pass it to the method?
Instead of:
[thingA, thingB] = createThings(...); // just a conceptual syntax of method returning two values, not valid in Java
Try:
thingA = createThingA(...);
thingB = createThingB(thingA, ...);
This should cover most of your needs, since in most situations one value is created before the other and you can split creating them in two methods. The drawback is that method createThingsB has an extra parameter comparing to createThings, and possibly you are passing exactly the same list of parameters twice to different methods.
Case two.
Most obvious solution ever and a simplified version of case one. It's not always possible, but maybe both of the values can be created independently of each other?
Instead of:
[thingA, thingB] = createThings(...); // see above
Try:
thingA = createThingA(...);
thingB = createThingB(...);
To make it more useful, these two methods can share some common logic:
public ThingA createThingA(...) {
doCommonThings(); // common logic
// create thing A
}
public ThingB createThingB(...) {
doCommonThings(); // common logic
// create thing B
}
Pass a list to your method and populate it, then return the String with the names, like this:
public String buildList(List<?> list) {
list.add(1);
list.add(2);
list.add(3);
return "something,something,something,dark side";
}
Then call it like this:
List<?> values = new ArrayList<?>();
String names = buildList(values);
You can utilize a HashMap<String, Object> as follows
public HashMap<String, Object> yourMethod()
{
.... different logic here
HashMap<String, Object> returnHashMap = new HashMap<String, Object>();
returnHashMap.put("objectA", objectAValue);
returnHashMap.put("myString", myStringValue);
returnHashMap.put("myBoolean", myBooleanValue);
return returnHashMap;
}
Then when calling the method in a different scope, you can cast each object back to its initial type:
// call the method
HashMap<String, Object> resultMap = yourMethod();
// fetch the results and cast them
ObjectA objectA = (ObjectA) resultMap.get("objectA");
String myString = (String) resultMap.get("myString");
Boolean myBoolean = (Boolean) resultMap.get("myBoolean");
I noticed there is no no-custom class, n-length, no-cast, type-safe answers yet to returning multiple values.
Here is my go:
import java.util.Objects;
public final class NTuple<V, T extends NTuple<?, ?>> {
private final V value;
private final T next;
private NTuple(V value, T next) {
this.value = value;
this.next = next;
}
public static <V> NTuple<V, ?> of(V value) {
return new NTuple<>(value, null);
}
public static <V, T extends NTuple<?, ?>> NTuple<V, T> of(V value, T next) {
return new NTuple<>(value, next);
}
public V value() {
return value;
}
public T next() {
return next;
}
public static <V> V unpack0(NTuple<V, ?> tuple) {
return Objects.requireNonNull(tuple, "0").value();
}
public static <V, T extends NTuple<V, ?>> V unpack1(NTuple<?, T> tuple) {
NTuple<?, T> tuple0 = Objects.requireNonNull(tuple, "0");
NTuple<V, ?> tuple1 = Objects.requireNonNull(tuple0.next(), "1");
return tuple1.value();
}
public static <V, T extends NTuple<?, NTuple<V, ?>>> V unpack2(NTuple<?, T> tuple) {
NTuple<?, T> tuple0 = Objects.requireNonNull(tuple, "0");
NTuple<?, NTuple<V, ?>> tuple1 = Objects.requireNonNull(tuple0.next(), "1");
NTuple<V, ?> tuple2 = Objects.requireNonNull(tuple1.next(), "2");
return tuple2.value();
}
}
Sample use:
public static void main(String[] args) {
// pre-java 10 without lombok - use lombok's var or java 10's var if you can
NTuple<String, NTuple<Integer, NTuple<Integer, ?>>> multiple = wordCount("hello world");
String original = NTuple.unpack0(multiple);
Integer wordCount = NTuple.unpack1(multiple);
Integer characterCount = NTuple.unpack2(multiple);
System.out.println(original + ": " + wordCount + " words " + characterCount + " chars");
}
private static NTuple<String, NTuple<Integer, NTuple<Integer, ?>>> wordCount(String s) {
int nWords = s.split(" ").length;
int nChars = s.length();
return NTuple.of(s, NTuple.of(nWords, NTuple.of(nChars)));
}
Pros:
no-custom container class - no need to write a class just for a return type
n-length - can handle any number of return values
no-cast - no need to cast from Object
type-safe - the types are checked via Java's generics
Cons:
inefficient for large numbers of return values
according to my experience with python's multiple return values, this should not happen in practice
heavy type declarations
can be alleviated by lombok/Java 10 var
In C, you would do it by passing pointers to placeholders for the results as arguments:
void getShoeAndWaistSizes(int *shoeSize, int *waistSize) {
*shoeSize = 36;
*waistSize = 45;
}
...
int shoeSize, waistSize;
getShoeAndWaistSize(&shoeSize, &waistSize);
int i = shoeSize + waistSize;
Let's try something similar, in Java.
void getShoeAndWaistSizes(List<Integer> shoeSize, List<Integer> waistSize) {
shoeSize.add(36);
waistSize.add(45);
}
...
List<Integer> shoeSize = new List<>();
List<Integer> waistSize = new List<>();
getShoeAndWaistSizes(shoeSize, waistSize);
int i = shoeSize.get(0) + waistSize.get(0);
PASS A HASH INTO THE METHOD AND POPULATE IT......
public void buildResponse(String data, Map response);

Looking for appropriate design pattern

Our code has several processors, each one having several api methods, where each method is overloaded also with same method that can accept collection.
For example:
public class Foo {
public X foo(Y y){...}
public Collection<X> foo(Collection<Y> y){... // iterate and execute foo(y) ... }
public Z bar(W w){...}
public Collection<Z> bar(Collection<W> w){... // iterate and execute bar(w) ... }
}
public class Other{
// also method and method on collection
}
Naturally, those methods on collections are actually duplication code of iteration.
What we are looking for, is kind of way to make some pattern or use generics, so the iteration over collection will be implemented once, also for that need a way to somehow pass the method name.
I'd suggest Startegy pattern. And do something like:
public interface Transformer<X, Y> {
Y transform( X input );
}
class Processor {
public <X,Y> Collection<Y> process( Collection<X> input, Transformer<X, Y> transformer) {
Collection<Y> ret = new LinkedList<Y>();
// generic loop, delegating transformation to specific transformer
for( X x : input) {
ret.add( transformer.transform( x ) );
}
return ret;
}
}
Example:
public static void main( String[] args ) {
List<String> strings = new LinkedList<String>();
strings.add( "1" );
strings.add( "2" );
strings.add( "3" );
Processor p = new Processor();
Collection<Integer> numbers = p.process( strings, new Transformer<String, Integer>() {
#Override
public Integer transform( String input ) {
return Integer.parseInt( input );
}
} );
}
I can't see how reflection could help here. You're trying to replace something as trivial as
public Collection<X> foo(Collection<Y> y) {
List<X> result = Lists.newArrayList();
for (Y e : y) result.add(foo(e));
return result;
}
by something probably much slower. I don't think that saving those 3 lines (several times) is worth it, but you might want to try either annotation processing (possibly without using annotations) or dynamic code generation. In both cases you'd write the original class as is without the collection methods and use a different one containing both the scalar and the collection methods.
Or you might want to make it more functionally styled:
public class Foo {
public final RichFunction<Y, X> foo = new RichFunction<Y, X>() {
X apply(Y y) {
return foo(y);
}
}
// after some refactoring the original method can be made private
// or inlined into the RichFunction
public X foo(Y y){...}
// instead of calling the original method like
// foo.foo(y)
// you'd use
// foo.foo.apply(y)
// which would work for both the scalar and collection methods
}
public abstract class RichFunction<K, V> extends com.google.common.base.Function<K, V> {
Collection<V> apply(Collection<K> keys) {
List<V> result = Lists.newArrayList();
for (K k : keys) result.add(apply(k));
return result;
}
}
RUAKH - I chosed to implement your suggestion for reflection (although, admit, I don't like reflection). So, I did something like the code below THANKS :)
public class Resource {
private static final int CLIENT_CODE_STACK_INDEX;
static {
// Finds out the index of "this code" in the returned stack trace - funny but it differs in JDK 1.5 and 1.6
int i = 0;
for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
i++;
if (ste.getClassName().equals(Resource.class.getName())) {
break;
}
}
CLIENT_CODE_STACK_INDEX = i;
}
public static String getCurrentMethodName() {
return Thread.currentThread().getStackTrace()[CLIENT_CODE_STACK_INDEX].getMethodName();
}
protected <IN,OUT> Collection<OUT> doMultiple(String methodName, Collection<IN> inCol, Class<?>... parameterTypes){
Collection<OUT> result = new ArrayList<OUT>();
try {
Method m = this.getClass().getDeclaredMethod(methodName, parameterTypes);
if (inCol==null || inCol.size()==0){
return result;
}
for (IN in : inCol){
Object o = m.invoke(this, in);
result.add((OUT) o);
}
}catch (Exception e){
e.printStackTrace();
}
return result;
}
}
public class FirstResource extends Resource{
public String doSomeThing(Integer i){
// LOTS OF LOGIC
return i.toString();
}
public Collection<String> doSomeThing(Collection<Integer> ints){
return doMultiple(getCurrentMethodName(), ints, Integer.class);
}
}
You should use Strategy pattern. By using Strategy pattern you can omit the usage if/else which makes the code more complex. Where strategy pattern creates less coupled code which is much simpler. By using Strategy pattern you can achieve more ways to configure code dynamically. So I would like to suggest you to use Strategy pattern.

How to return multiple objects from a Java method?

I want to return two objects from a Java method and was wondering what could be a good way of doing so?
The possible ways I can think of are: return a HashMap (since the two Objects are related) or return an ArrayList of Object objects.
To be more precise, the two objects I want to return are (a) List of objects and (b) comma separated names of the same.
I want to return these two Objects from one method because I dont want to iterate through the list of objects to get the comma separated names (which I can do in the same loop in this method).
Somehow, returning a HashMap does not look a very elegant way of doing so.
If you want to return two objects you usually want to return a single object that encapsulates the two objects instead.
You could return a List of NamedObject objects like this:
public class NamedObject<T> {
public final String name;
public final T object;
public NamedObject(String name, T object) {
this.name = name;
this.object = object;
}
}
Then you can easily return a List<NamedObject<WhateverTypeYouWant>>.
Also: Why would you want to return a comma-separated list of names instead of a List<String>? Or better yet, return a Map<String,TheObjectType> with the keys being the names and the values the objects (unless your objects have specified order, in which case a NavigableMap might be what you want.
If you know you are going to return two objects, you can also use a generic pair:
public class Pair<A,B> {
public final A a;
public final B b;
public Pair(A a, B b) {
this.a = a;
this.b = b;
}
};
Edit A more fully formed implementation of the above:
package util;
public class Pair<A,B> {
public static <P, Q> Pair<P, Q> makePair(P p, Q q) {
return new Pair<P, Q>(p, q);
}
public final A a;
public final B b;
public Pair(A a, B b) {
this.a = a;
this.b = b;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((a == null) ? 0 : a.hashCode());
result = prime * result + ((b == null) ? 0 : b.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
#SuppressWarnings("rawtypes")
Pair other = (Pair) obj;
if (a == null) {
if (other.a != null) {
return false;
}
} else if (!a.equals(other.a)) {
return false;
}
if (b == null) {
if (other.b != null) {
return false;
}
} else if (!b.equals(other.b)) {
return false;
}
return true;
}
public boolean isInstance(Class<?> classA, Class<?> classB) {
return classA.isInstance(a) && classB.isInstance(b);
}
#SuppressWarnings("unchecked")
public static <P, Q> Pair<P, Q> cast(Pair<?, ?> pair, Class<P> pClass, Class<Q> qClass) {
if (pair.isInstance(pClass, qClass)) {
return (Pair<P, Q>) pair;
}
throw new ClassCastException();
}
}
Notes, mainly around rustiness with Java & generics:
both a and b are immutable.
makePair static method helps you with boiler plate typing, which the diamond operator in Java 7 will make less annoying. There's some work to make this really nice re: generics, but it should be ok-ish now. (c.f. PECS)
hashcode and equals are generated by eclipse.
the compile time casting in the cast method is ok, but doesn't seem quite right.
I'm not sure if the wildcards in isInstance are necessary.
I've just written this in response to comments, for illustration purposes only.
In the event the method you're calling is private, or called from one location, try
return new Object[]{value1, value2};
The caller looks like:
Object[] temp=myMethod(parameters);
Type1 value1=(Type1)temp[0]; //For code clarity: temp[0] is not descriptive
Type2 value2=(Type2)temp[1];
The Pair example by David Hanak has no syntactic benefit, and is limited to two values.
return new Pair<Type1,Type2>(value1, value2);
And the caller looks like:
Pair<Type1, Type2> temp=myMethod(parameters);
Type1 value1=temp.a; //For code clarity: temp.a is not descriptive
Type2 value2=temp.b;
You may use any of following ways:
private static final int RETURN_COUNT = 2;
private static final int VALUE_A = 0;
private static final int VALUE_B = 1;
private static final String A = "a";
private static final String B = "b";
1) Using Array
private static String[] methodWithArrayResult() {
//...
return new String[]{"valueA", "valueB"};
}
private static void usingArrayResultTest() {
String[] result = methodWithArrayResult();
System.out.println();
System.out.println("A = " + result[VALUE_A]);
System.out.println("B = " + result[VALUE_B]);
}
2) Using ArrayList
private static List<String> methodWithListResult() {
//...
return Arrays.asList("valueA", "valueB");
}
private static void usingListResultTest() {
List<String> result = methodWithListResult();
System.out.println();
System.out.println("A = " + result.get(VALUE_A));
System.out.println("B = " + result.get(VALUE_B));
}
3) Using HashMap
private static Map<String, String> methodWithMapResult() {
Map<String, String> result = new HashMap<>(RETURN_COUNT);
result.put(A, "valueA");
result.put(B, "valueB");
//...
return result;
}
private static void usingMapResultTest() {
Map<String, String> result = methodWithMapResult();
System.out.println();
System.out.println("A = " + result.get(A));
System.out.println("B = " + result.get(B));
}
4) Using your custom container class
private static class MyContainer<M,N> {
private final M first;
private final N second;
public MyContainer(M first, N second) {
this.first = first;
this.second = second;
}
public M getFirst() {
return first;
}
public N getSecond() {
return second;
}
// + hashcode, equals, toString if need
}
private static MyContainer<String, String> methodWithContainerResult() {
//...
return new MyContainer("valueA", "valueB");
}
private static void usingContainerResultTest() {
MyContainer<String, String> result = methodWithContainerResult();
System.out.println();
System.out.println("A = " + result.getFirst());
System.out.println("B = " + result.getSecond());
}
5) Using AbstractMap.simpleEntry
private static AbstractMap.SimpleEntry<String, String> methodWithAbstractMapSimpleEntryResult() {
//...
return new AbstractMap.SimpleEntry<>("valueA", "valueB");
}
private static void usingAbstractMapSimpleResultTest() {
AbstractMap.SimpleEntry<String, String> result = methodWithAbstractMapSimpleEntryResult();
System.out.println();
System.out.println("A = " + result.getKey());
System.out.println("B = " + result.getValue());
}
6) Using Pair of Apache Commons
private static Pair<String, String> methodWithPairResult() {
//...
return new ImmutablePair<>("valueA", "valueB");
}
private static void usingPairResultTest() {
Pair<String, String> result = methodWithPairResult();
System.out.println();
System.out.println("A = " + result.getKey());
System.out.println("B = " + result.getValue());
}
I almost always end up defining n-Tuple classes when I code in Java. For instance:
public class Tuple2<T1,T2> {
private T1 f1;
private T2 f2;
public Tuple2(T1 f1, T2 f2) {
this.f1 = f1; this.f2 = f2;
}
public T1 getF1() {return f1;}
public T2 getF2() {return f2;}
}
I know it's a bit ugly, but it works, and you just have to define your tuple types once. Tuples are something Java really lacks.
EDIT: David Hanak's example is more elegant, as it avoids defining getters and still keeps the object immutable.
Before Java 5, I would kind of agree that the Map solution isn't ideal. It wouldn't give you compile time type checking so can cause issues at runtime. However, with Java 5, we have Generic Types.
So your method could look like this:
public Map<String, MyType> doStuff();
MyType of course being the type of object you are returning.
Basically I think that returning a Map is the right solution in this case because that's exactly what you want to return - a mapping of a string to an object.
Apache Commons has tuple and triple for this:
ImmutablePair<L,R> An immutable pair consisting of two Object
elements.
ImmutableTriple<L,M,R> An immutable triple consisting of
three Object elements.
MutablePair<L,R> A mutable pair consisting of
two Object elements.
MutableTriple<L,M,R> A mutable triple
consisting of three Object elements.
Pair<L,R> A pair consisting of
two elements.
Triple<L,M,R> A triple consisting of three elements.
Source: https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/tuple/package-summary.html
Alternatively, in situations where I want to return a number of things from a method I will sometimes use a callback mechanism instead of a container. This works very well in situations where I cannot specify ahead of time just how many objects will be generated.
With your particular problem, it would look something like this:
public class ResultsConsumer implements ResultsGenerator.ResultsCallback
{
public void handleResult( String name, Object value )
{
...
}
}
public class ResultsGenerator
{
public interface ResultsCallback
{
void handleResult( String aName, Object aValue );
}
public void generateResults( ResultsGenerator.ResultsCallback aCallback )
{
Object value = null;
String name = null;
...
aCallback.handleResult( name, value );
}
}
While in your case, the comment may be a good way to go, in Android, you can use Pair . Simply
return new Pair<>(yourList, yourCommaSeparatedValues);
Use of following Entry object
Example :
public Entry<A,B> methodname(arg)
{
.......
return new AbstractMap.simpleEntry<A,B>(instanceOfA,instanceOfB);
}
Regarding the issue about multiple return values in general I usually use a small helper class that wraps a single return value and is passed as parameter to the method:
public class ReturnParameter<T> {
private T value;
public ReturnParameter() { this.value = null; }
public ReturnParameter(T initialValue) { this.value = initialValue; }
public void set(T value) { this.value = value; }
public T get() { return this.value; }
}
(for primitive datatypes I use minor variations to directly store the value)
A method that wants to return multiple values would then be declared as follows:
public void methodThatReturnsTwoValues(ReturnParameter<ClassA> nameForFirstValueToReturn, ReturnParameter<ClassB> nameForSecondValueToReturn) {
//...
nameForFirstValueToReturn.set("...");
nameForSecondValueToReturn.set("...");
//...
}
Maybe the major drawback is that the caller has to prepare the return objects in advance in case he wants to use them (and the method should check for null pointers)
ReturnParameter<ClassA> nameForFirstValue = new ReturnParameter<ClassA>();
ReturnParameter<ClassB> nameForSecondValue = new ReturnParameter<ClassB>();
methodThatReturnsTwoValues(nameForFirstValue, nameForSecondValue);
Advantages (in comparison to other solutions proposed):
You do not have to create a special class declaration for individual methods and its return types
The parameters get a name and therefore are easier to differentiate when looking at the method signature
Type safety for each parameter
All possible solutions will be a kludge (like container objects, your HashMap idea, “multiple return values” as realized via arrays). I recommend regenerating the comma-separated list from the returned List. The code will end up being a lot cleaner.
Keep it simple and create a class for multiple result situation. This example accepts an ArrayList and a message text from a databasehelper getInfo.
Where you call the routine that returns multiple values you code:
multResult res = mydb.getInfo();
In the routine getInfo you code:
ArrayList<String> list= new ArrayList<String>();
add values to the list...
return new multResult("the message", list);
and define a class multResult with:
public class multResult {
public String message; // or create a getter if you don't like public
public ArrayList<String> list;
multResult(String m, ArrayList<String> l){
message = m;
list= l;
}
}
As I see it there are really three choices here and the solution depends on the context. You can choose to implement the construction of the name in the method that produces the list. This is the choice you've chosen, but I don't think it is the best one. You are creating a coupling in the producer method to the consuming method that doesn't need to exist. Other callers may not need the extra information and you would be calculating extra information for these callers.
Alternatively, you could have the calling method calculate the name. If there is only one caller that needs this information, you can stop there. You have no extra dependencies and while there is a little extra calculation involved, you've avoided making your construction method too specific. This is a good trade-off.
Lastly, you could have the list itself be responsible for creating the name. This is the route I would go if the calculation needs to be done by more than one caller. I think this puts the responsibility for the creation of the names with the class that is most closely related to the objects themselves.
In the latter case, my solution would be to create a specialized List class that returns a comma-separated string of the names of objects that it contains. Make the class smart enough that it constructs the name string on the fly as objects are added and removed from it. Then return an instance of this list and call the name generation method as needed. Although it may be almost as efficient (and simpler) to simply delay calculation of the names until the first time the method is called and store it then (lazy loading). If you add/remove an object, you need only remove the calculated value and have it get recalculated on the next call.
Can do some thing like a tuple in dynamic language (Python)
public class Tuple {
private Object[] multiReturns;
private Tuple(Object... multiReturns) {
this.multiReturns = multiReturns;
}
public static Tuple _t(Object... multiReturns){
return new Tuple(multiReturns);
}
public <T> T at(int index, Class<T> someClass) {
return someClass.cast(multiReturns[index]);
}
}
and use like this
public Tuple returnMultiValues(){
return Tuple._t(new ArrayList(),new HashMap())
}
Tuple t = returnMultiValues();
ArrayList list = t.at(0,ArrayList.class);
I followed a similar approach than the described in the other answers with a few tweaks based on the requirement I had, basically I created the following classes(Just in case, everything is Java):
public class Pair<L, R> {
final L left;
final R right;
public Pair(L left, R right) {
this.left = left;
this.right = right;
}
public <T> T get(Class<T> param) {
return (T) (param == this.left.getClass() ? this.left : this.right);
}
public static <L, R> Pair<L, R> of(L left, R right) {
return new Pair<L, R>(left, right);
}
}
Then, my requirement was simple, in the repository Class that reaches the DB, for the Get Methods than retrieve data from the DB, I need to check if it failed or succeed, then, if succeed, I needed to play with the returning list, if failed, stop the execution and notify the error.
So, for example, my methods are like this:
public Pair<ResultMessage, List<Customer>> getCustomers() {
List<Customer> list = new ArrayList<Customer>();
try {
/*
* Do some work to get the list of Customers from the DB
* */
} catch (SQLException e) {
return Pair.of(
new ResultMessage(e.getErrorCode(), e.getMessage()), // Left
null); // Right
}
return Pair.of(
new ResultMessage(0, "SUCCESS"), // Left
list); // Right
}
Where ResultMessage is just a class with two fields (code/message) and Customer is any class with a bunch of fields that comes from the DB.
Then, to check the result I just do this:
void doSomething(){
Pair<ResultMessage, List<Customer>> customerResult = _repository.getCustomers();
if (customerResult.get(ResultMessage.class).getCode() == 0) {
List<Customer> listOfCustomers = customerResult.get(List.class);
System.out.println("do SOMETHING with the list ;) ");
}else {
System.out.println("Raised Error... do nothing!");
}
}
In C++ (STL) there is a pair class for bundling two objects. In Java Generics a pair class isn't available, although there is some demand for it. You could easily implement it yourself though.
I agree however with some other answers that if you need to return two or more objects from a method, it would be better to encapsulate them in a class.
Why not create a WhateverFunctionResult object that contains your results, and the logic required to parse these results, iterate over then etc. It seems to me that either:
These results objects are intimately tied together/related and belong together, or:
they are unrelated, in which case your function isn't well defined in terms of what it's trying to do (i.e. doing two different things)
I see this sort of issue crop up again and again. Don't be afraid to create your own container/result classes that contain the data and the associated functionality to handle this. If you simply pass the stuff around in a HashMap or similar, then your clients have to pull this map apart and grok the contents each time they want to use the results.
public class MultipleReturnValues {
public MultipleReturnValues() {
}
public static void functionWithSeveralReturnValues(final String[] returnValues) {
returnValues[0] = "return value 1";
returnValues[1] = "return value 2";
}
public static void main(String[] args) {
String[] returnValues = new String[2];
functionWithSeveralReturnValues(returnValues);
System.out.println("returnValues[0] = " + returnValues[0]);
System.out.println("returnValues[1] = " + returnValues[1]);
}
}
This is not exactly answering the question, but since every of the solution given here has some drawbacks, I suggest to try to refactor your code a little bit so you need to return only one value.
Case one.
You need something inside as well as outside of your method. Why not calculate it outside and pass it to the method?
Instead of:
[thingA, thingB] = createThings(...); // just a conceptual syntax of method returning two values, not valid in Java
Try:
thingA = createThingA(...);
thingB = createThingB(thingA, ...);
This should cover most of your needs, since in most situations one value is created before the other and you can split creating them in two methods. The drawback is that method createThingsB has an extra parameter comparing to createThings, and possibly you are passing exactly the same list of parameters twice to different methods.
Case two.
Most obvious solution ever and a simplified version of case one. It's not always possible, but maybe both of the values can be created independently of each other?
Instead of:
[thingA, thingB] = createThings(...); // see above
Try:
thingA = createThingA(...);
thingB = createThingB(...);
To make it more useful, these two methods can share some common logic:
public ThingA createThingA(...) {
doCommonThings(); // common logic
// create thing A
}
public ThingB createThingB(...) {
doCommonThings(); // common logic
// create thing B
}
Pass a list to your method and populate it, then return the String with the names, like this:
public String buildList(List<?> list) {
list.add(1);
list.add(2);
list.add(3);
return "something,something,something,dark side";
}
Then call it like this:
List<?> values = new ArrayList<?>();
String names = buildList(values);
You can utilize a HashMap<String, Object> as follows
public HashMap<String, Object> yourMethod()
{
.... different logic here
HashMap<String, Object> returnHashMap = new HashMap<String, Object>();
returnHashMap.put("objectA", objectAValue);
returnHashMap.put("myString", myStringValue);
returnHashMap.put("myBoolean", myBooleanValue);
return returnHashMap;
}
Then when calling the method in a different scope, you can cast each object back to its initial type:
// call the method
HashMap<String, Object> resultMap = yourMethod();
// fetch the results and cast them
ObjectA objectA = (ObjectA) resultMap.get("objectA");
String myString = (String) resultMap.get("myString");
Boolean myBoolean = (Boolean) resultMap.get("myBoolean");
I noticed there is no no-custom class, n-length, no-cast, type-safe answers yet to returning multiple values.
Here is my go:
import java.util.Objects;
public final class NTuple<V, T extends NTuple<?, ?>> {
private final V value;
private final T next;
private NTuple(V value, T next) {
this.value = value;
this.next = next;
}
public static <V> NTuple<V, ?> of(V value) {
return new NTuple<>(value, null);
}
public static <V, T extends NTuple<?, ?>> NTuple<V, T> of(V value, T next) {
return new NTuple<>(value, next);
}
public V value() {
return value;
}
public T next() {
return next;
}
public static <V> V unpack0(NTuple<V, ?> tuple) {
return Objects.requireNonNull(tuple, "0").value();
}
public static <V, T extends NTuple<V, ?>> V unpack1(NTuple<?, T> tuple) {
NTuple<?, T> tuple0 = Objects.requireNonNull(tuple, "0");
NTuple<V, ?> tuple1 = Objects.requireNonNull(tuple0.next(), "1");
return tuple1.value();
}
public static <V, T extends NTuple<?, NTuple<V, ?>>> V unpack2(NTuple<?, T> tuple) {
NTuple<?, T> tuple0 = Objects.requireNonNull(tuple, "0");
NTuple<?, NTuple<V, ?>> tuple1 = Objects.requireNonNull(tuple0.next(), "1");
NTuple<V, ?> tuple2 = Objects.requireNonNull(tuple1.next(), "2");
return tuple2.value();
}
}
Sample use:
public static void main(String[] args) {
// pre-java 10 without lombok - use lombok's var or java 10's var if you can
NTuple<String, NTuple<Integer, NTuple<Integer, ?>>> multiple = wordCount("hello world");
String original = NTuple.unpack0(multiple);
Integer wordCount = NTuple.unpack1(multiple);
Integer characterCount = NTuple.unpack2(multiple);
System.out.println(original + ": " + wordCount + " words " + characterCount + " chars");
}
private static NTuple<String, NTuple<Integer, NTuple<Integer, ?>>> wordCount(String s) {
int nWords = s.split(" ").length;
int nChars = s.length();
return NTuple.of(s, NTuple.of(nWords, NTuple.of(nChars)));
}
Pros:
no-custom container class - no need to write a class just for a return type
n-length - can handle any number of return values
no-cast - no need to cast from Object
type-safe - the types are checked via Java's generics
Cons:
inefficient for large numbers of return values
according to my experience with python's multiple return values, this should not happen in practice
heavy type declarations
can be alleviated by lombok/Java 10 var
In C, you would do it by passing pointers to placeholders for the results as arguments:
void getShoeAndWaistSizes(int *shoeSize, int *waistSize) {
*shoeSize = 36;
*waistSize = 45;
}
...
int shoeSize, waistSize;
getShoeAndWaistSize(&shoeSize, &waistSize);
int i = shoeSize + waistSize;
Let's try something similar, in Java.
void getShoeAndWaistSizes(List<Integer> shoeSize, List<Integer> waistSize) {
shoeSize.add(36);
waistSize.add(45);
}
...
List<Integer> shoeSize = new List<>();
List<Integer> waistSize = new List<>();
getShoeAndWaistSizes(shoeSize, waistSize);
int i = shoeSize.get(0) + waistSize.get(0);
PASS A HASH INTO THE METHOD AND POPULATE IT......
public void buildResponse(String data, Map response);

Categories