0

This is more of a logical question than code specific, I have some twenty functions, each function calculates two values of my interest. However I can only return one value from a function. Now the other option I have is to make a class and implement setter and getter with global variables. I want to know if this is a feasible and recommended way? Or there is a better way to do this?

10 Answers 10

3

Don't use global variables! Use some class that has your data as private fileds, and provide getters for it. Like in

class Pair<A,B> {
    final A one;
    final B two;
    public Pair(A fst, B snd) { one = fst; two = snd; }
    public A getFst() { return one; }
    public B getSnd() { return two; }
}

Then you can elsewhere say something like:

    return new Pair(42, "a result");
Sign up to request clarification or add additional context in comments.

1 Comment

A better proposal for preserving multiple type.+1 :)
1

Return a Collection from your function containing your values of interest.

2 Comments

An Array list you mean? That way I don't need to split it into two classes. Though I might be compelled to think about type safety.
Depends what you intent to return. If they are unique value you might use a Set or if they are key-value you might use a Map.
1

Depends on the problem. But 2 solutions are :

  1. Make new class which instances will be returned by all this functions. This class would have 2 attributes for each needed answer.
  2. Return array or Collection with this 2 answers.

Comments

1

You have to return a List or a array.

But if return types are different you can create custom class and use it as return type.

Example

public class Result {
   private String name;
   private int age;

  // getters and setters;   
}

Now you can have some thing like following

public static Result getInfo(){
    Result result=new Result();
    result.setName("name");
    result.setAge(10);
    return result;//now you can have String and int values return from the method
}

1 Comment

I think in my case the second option is preferred, my data types are very varied and a floating point difference can cause me problems.
1

There are many ways: collections, arrays ... In my opinion the only way is to define a class with these values. you do not need getter and setter methods if you don't need to regulate the visibility of the contents

class MyReturnValue {
  public int a;
  public int b;
}

in your code:

...
MyReturnValue result=new MyReturnValue();
result.a=5;
result.b=6;

return result;

Comments

1

It is better to make a class and implement setter and getter with global variables rather than to Return Collection further it depends on your use.

Comments

1

You can do this

long[] function() {
    long[] ret = { a, b };
    return ret;
}

or

long[] a = { 0 }, b = { 0 };

void function(long[] a, long[] b) {
    a[0] = ...
    b[0] = ...

or add properties to an object.

private long a,b;

void function() {
    a = ...
    b = ...
}

in the last case you can value.

class Results {
    public final long a;
    public final Date b; // note: Date is not immutable.
    // add constructor
}

public Results function() {
    long a = ...
    Date b = ...
    return new Results(a, b);
}

6 Comments

Type safety is an issue.
@user2822178 What are your calculated types?
I would like to discourage against #2, i.e. having the method affect the object's state. Of course it may be appropriate in certain contexts, but in general it should probably be avoided.
@Smallhacker I agree that all of them should be avoided, returning multiple values should be avoided.
@user2822178 all of these could be a long but I take your point that you want to check types. In this case I suggest option 3 where you have a new object for each function.
|
1

I think making a Record class is the most suitable.

public class Record {
    public final int a;
    public final int b;

    public Record(final int a, final int b) {
        this.a = a;
        this.b = b;
    }
}

Then your functions can return type Record, and you can access it with let's say record.a and record.b.

This is also one of the few cases where public variables and no getters and setters can be justified.

UPDATE: Implemented a proposed change, now everything is final, which means that Record cannot be modified when you get it back, which seems to be in line with expectations. You only want the results and use those.

2 Comments

I'd avoid the no-arg constructor and make the fields final, but otherwise a custom record is the cleanest solution...
@GyroGearless True, fixed it, that's indeed the case if all you want is to have two values returned.
1

What about adopting varargs with generic helper function for getting around of number of returning variable limitation: In this solution, we won't have to declare a new class every time when number of returning variable changes.

class Results
{
    private final Object[] returnedObj;

    public Results(Object... returnedObj) 
    {
        this.returnedObj = returnedObj;
    }

    public <E> E getResult(int index)
    {
        return (E)returnedObj[index];
    }


}

Test case:

public static Results Test()
{
        return new Results(12, "ABCD EFG", 12.45);
             // or return larger number of value
}

//// And then returning the result

Results result = Test();
String x = result.<String>getResult(1);
System.out.println(x); // prints "ABCD EFG"

1 Comment

Great this solution!!
0

You could even return the values separated by a special character say a "~" if you are sure that the "~" won't appear in your results.

1 Comment

An ugly hack - perhaps COBOL introduced records more than half a century ago!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.