Need to return multiple values.

N

Nafai

Hello. I have a method like this:


public void p(Integer a, Integer b, Integer c)
{
....
}

b and c should be output data and a input.

But I don't know how to assing a value to b and c inside p without
changin the objet where they point.

That is:

public void p(X a, Integer b, Integer c)
{
...
b = doSomeThing(a);
c = doSomeThing2(a);
}

That doesn't make b and c to point to the result of doSomeThing(a) when
p ends.

What can I do?

Thank-you.
 
D

David Alex Lamb

Hello. I have a method like this:


public void p(Integer a, Integer b, Integer c)
{
...
}

b and c should be output data and a input.

But I don't know how to assing a value to b and c inside p without
changin the objet where they point.

That is:

public void p(X a, Integer b, Integer c)
{
...
b = doSomeThing(a);
c = doSomeThing2(a);
}

That doesn't make b and c to point to the result of doSomeThing(a) when
p ends.

1) Return an object containing b and c (don't pass them as parameters, or
2) Pass a parameter with b and c members, which get assigned in p, or
3) Let callers of p call doSomeThing and doSomething2 directly, e.g.
x = Quotient(m,n) // quotient of m/n
y = Remainder(m,n) // remainder of m/n
 
E

Eric Sosman

Nafai said:
Hello. I have a method like this:


public void p(Integer a, Integer b, Integer c)
{
...
}

b and c should be output data and a input.

But I don't know how to assing a value to b and c inside p without
changin the objet where they point.

That is:

public void p(X a, Integer b, Integer c)
{
...
b = doSomeThing(a);
c = doSomeThing2(a);
}

That doesn't make b and c to point to the result of doSomeThing(a) when
p ends.

What can I do?

There are many solutions, with different advantages
and drawbacks. One of the simplest is

public Integer[] p(X a) {
Integer[] result = new Integer[2];
...
result[0] = doSomeThing(a);
result[1] = doSomething2(a);
...
return result;
}
 
A

Alex

Integer is immutable (like String, for example).
So, use mutable objects if you _really_ need to change them in this
way.
Which is definitely not recommended as good OP.

int i[]=new int[5];
i[2]=2;
call(i);
.....
public void call(int a[]) {
a[2]=22;
}

Alex Kizub.
 
J

Joona I Palaste

Nafai <[email protected]> scribbled the following
Hello. I have a method like this:

public void p(Integer a, Integer b, Integer c)
{
...
}
b and c should be output data and a input.
But I don't know how to assing a value to b and c inside p without
changin the objet where they point.
public void p(X a, Integer b, Integer c)
{
...
b = doSomeThing(a);
c = doSomeThing2(a);
}
That doesn't make b and c to point to the result of doSomeThing(a) when
p ends.
What can I do?
Thank-you.

Others have already answered your question. I only want to add that I
have theorised about adding aggregate types, found in functional
languages, to languages such as C or Java. In this example, it would
work like this:

public (Integer, Integer) p(X a)
{
return (doSomething(a), doSomething2(a));
}

and then called like this:

(b, c) = p(a);

The only problem is that if "b" and "c" are the same variable then the
behaviour is undefined. I have not found a solution to this, and seeing
as the entire problem is theoretical at best, I have not bothered to
try.
 
H

Heiner Kücker

Joona I Palaste
public (Integer, Integer) p(X a)
{
return (doSomething(a), doSomething2(a));
}

and then called like this:

(b, c) = p(a);

The only problem is that if "b" and "c" are the same variable then the
behaviour is undefined. I have not found a solution to this, and seeing
as the entire problem is theoretical at best, I have not bothered to
try.

Simply solution is, the compiler have to complain about the ambigous variable using.

Heiner Kuecker
Internet: http://www.heinerkuecker.de http://www.heiner-kuecker.de
JSP WorkFlow PageFlow Page Flow FlowControl Navigation: http://www.control-and-command.de
Java Expression Formula Parser: http://www.heinerkuecker.de/Expression.html
Domain Specific Languages http://www.heinerkuecker.de/DomainParser.html
 
Y

Yamin

Hey Nafai,

As others have mentioned, Integer is immutable for its own reasons.
I've often wondered why they didn't have an easy to use IntegerBuffer,
like they have StringBuffer. They have intBuffer, but its not quite
what you'd want.

So these are the basic options:
1. create a custom structure just for the function (I don't like doing
this)
2. Pass an array of objects
3. Use a Map
4. Define your own mutable Integer class.

I like to use 3 in cases where performance is not an issue. It helps
keep the function definition simple.

Use strings as keys...just use the parameter names.
//pass the parameters into the function
HashMap abc;
abc.put("a", a);
abc.put("b", b);
abc.put("c", c);

//Extract them
public void p(HashMap abc)
{
Integer a = HashMap.get("a");
Integer b = HashMap.get("b");
Integer c = HashMap.get("c");
}


This beats an array IMO because ur not dealing with indices which you
could screw up if you change the number of parameters of whatever...

Yamin
 
H

Heiner Kücker

Yamin
Hey Nafai,

As others have mentioned, Integer is immutable for its own reasons.
I've often wondered why they didn't have an easy to use IntegerBuffer,
like they have StringBuffer. They have intBuffer, but its not quite
what you'd want.

So these are the basic options:
1. create a custom structure just for the function (I don't like doing
this)
2. Pass an array of objects
3. Use a Map
4. Define your own mutable Integer class.

I like to use 3 in cases where performance is not an issue. It helps
keep the function definition simple.

Use strings as keys...just use the parameter names.
//pass the parameters into the function
HashMap abc;
abc.put("a", a);
abc.put("b", b);
abc.put("c", c);

//Extract them
public void p(HashMap abc)
{
Integer a = HashMap.get("a");
Integer b = HashMap.get("b");
Integer c = HashMap.get("c");
}


This beats an array IMO because ur not dealing with indices which you
could screw up if you change the number of parameters of whatever...

What yout meant are named parameters.
A good thing if the compiler supported this.

--
Heiner Kuecker
Internet: http://www.heinerkuecker.de http://www.heiner-kuecker.de
JSP WorkFlow PageFlow Page Flow FlowControl Navigation: http://www.control-and-command.de
Java Expression Formula Parser: http://www.heinerkuecker.de/Expression.html
Domain Specific Languages http://www.heinerkuecker.de/DomainParser.html
 
D

dbr

What yout meant are named parameters.
A good thing if the compiler supported this.

You might want to check the Nice language, which is an extension of
Java that does support named parameters. It also supports tuples, which
allows methods to return multiple values.

http://nice.sf.net

As to what
(x,x) = (1,2);
should do, I think it makes to follow, as usual, the left-to-right
evaluation order. So first x is assigned 1, then x is assigned 2.

Daniel Bonniot
 
S

surferjeff

dbr said:
You might want to check the Nice language, which is an extension of
Java that does support named parameters. It also supports tuples, which
allows methods to return multiple values.

http://nice.sf.net

As to what
(x,x) = (1,2);
should do, I think it makes to follow, as usual, the left-to-right
evaluation order. So first x is assigned 1, then x is assigned 2.

Daniel Bonniot

Python has this exact syntax:

a, b = 1, 2

It's pretty easy to do in C++ too:

pair<int,int> MyFunction(int a) {
...
return pair<int,int>(b, c);
}
 
J

Joona I Palaste

(e-mail address removed) scribbled the following
Python has this exact syntax:
a, b = 1, 2
It's pretty easy to do in C++ too:
pair<int,int> MyFunction(int a) {
...
return pair<int,int>(b, c);
}

Yes, but how do you assign the values from your pair<int, int> to two
int variables such as a and b? I don't know C++ very well, so I don't
know how, or if, it can be done.
 
R

Ryan Stewart

[...]
public (Integer, Integer) p(X a)
{
return (doSomething(a), doSomething2(a));
}

and then called like this:

(b, c) = p(a);

The only problem is that if "b" and "c" are the same variable then the
behaviour is undefined. I have not found a solution to this, and seeing
as the entire problem is theoretical at best, I have not bothered to
try.
I'd say you would define the expression to be the same as:
b = p(a)[first return value];
c = p(a)[second return value];

Therefore if both b and c are the same somehow, they would both end up having
the second return value.
 
J

Joona I Palaste

Ryan Stewart <[email protected]> scribbled the following
[...]
public (Integer, Integer) p(X a)
{
return (doSomething(a), doSomething2(a));
}

and then called like this:

(b, c) = p(a);

The only problem is that if "b" and "c" are the same variable then the
behaviour is undefined. I have not found a solution to this, and seeing
as the entire problem is theoretical at best, I have not bothered to
try.
I'd say you would define the expression to be the same as:
b = p(a)[first return value];
c = p(a)[second return value];
Therefore if both b and c are the same somehow, they would both end up having
the second return value.

Good, thanks. Now should I write a JSR about this? Or has someone
already written one?

--
/-- Joona Palaste ([email protected]) ------------- Finland --------\
\-------------------------------------------------------- rules! --------/
"And according to Occam's Toothbrush, we only need to optimise the most frequent
instructions."
- Teemu Kerola
 
X

xarax

Joona I Palaste said:
Ryan Stewart <[email protected]> scribbled the following
[...]
public (Integer, Integer) p(X a)
{
return (doSomething(a), doSomething2(a));
}

and then called like this:

(b, c) = p(a);

The only problem is that if "b" and "c" are the same variable then the
behaviour is undefined. I have not found a solution to this, and seeing
as the entire problem is theoretical at best, I have not bothered to
try.
I'd say you would define the expression to be the same as:
b = p(a)[first return value];
c = p(a)[second return value];
Therefore if both b and c are the same somehow, they would both end up having
the second return value.

Good, thanks. Now should I write a JSR about this? Or has someone
already written one?

It will likely be rejected. The traditional ways of returning
multiple values are:

1. Pass a reference to output container object as input parameter.

2. Return an array.

3. Return a container object.

These techniques are so easy to use and understand, that
I doubt that changing the language to accommodate your
suggestion will happen.
 
S

Stefan Schulz

Hello. I have a method like this:


public void p(Integer a, Integer b, Integer c)
{
...
}

b and c should be output data and a input.

But I don't know how to assing a value to b and c inside p without
changin the objet where they point.

That is:

public void p(X a, Integer b, Integer c)
{
...
b = doSomeThing(a);
c = doSomeThing2(a);
}

That doesn't make b and c to point to the result of doSomeThing(a) when
p ends.

What can I do?

Why not use some Pair class?

import java.io.Serializable;

/**
* convenience class for pairs of values. This class provides basic type
* safety, and can be used as a {@link java.util.Map}-key, and similar.
*
* Note that Serialization can only occur successfully if the type parameters T1
* and T2 also implement the {@link java.io.Serializable} interface.
*
*/
public class Pair<T1, T2> implements Serializable, Cloneable {

private static final long serialVersionUID = 3690473610825577009L;

private final T1 first;
private final T2 second;

/**
* creates a new Pair of values.
* @param first first value
* @param second second value
*/

public Pair(T1 first, T2 second) {
this.first = first;
this.second = second;
}

/**
* retrieves the first value of pair.
*
* @return the first value
*/

public T1 getFirst() {
return first;
}

/**
* retrieves the second value of pair.
*
* @return the second value
*/
public T2 getSecond() {
return second;
}

/**
* computes the hashcode for this object. This implementation is
* consistent with equals, if the member objects have hashcodes that
* are consistent with equals. It handles null-values gracefully.
*
* @return the hashcode
*/
@Override
public int hashCode(){
int firstCode = first != null ? first.hashCode() : 0;
int secondCode = second != null ? second.hashCode() >> 1 : 0;
return firstCode ^ secondCode;
}

/**
* compares two objects of class Pair for equality. A pair is equal if
* it's members either fulfill reference equality (==) or if their
* equals(Object) methods both return true.
*
* @param o another object
* @return true if the pairs are equal
*/
@Override
public boolean equals(Object o){
if (o == this)
return true;

if (o == null)
return false;

if (o instanceof Pair){
Pair<?,?> that = (Pair<?,?>) o;
Object thatFirst = that.getFirst();
Object thatSecond = that.getSecond();

if (thatFirst != first){
if (first == null || !first.equals(thatFirst))
return false;
}

if (thatSecond != second){
if (second == null || !second.equals(thatSecond))
return false;
}

return true;
}

return false;
}

/**
* returns a shallow copy of this Pair. The copy may be quicker
* then the obvious new Pair<T1, T2>(this.getFirst(), this.getSecond())
* method of copying.
*
* @return a copy of this object.
*/

@Override
@SuppressWarnings("unchecked")
public Pair<T1, T2> clone(){
try {
return (Pair<T1, T2>) super.clone();
} catch (CloneNotSupportedException e) {
throw new AssertionError(e);
}
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top