returning multiple entities from a method

O

Oliver Wong

Kenneth P. Turvey said:
I'm not sure where you are getting the error then. Why don't you post a
snippet of your code and we'll look at it.

I'm relatively confident the exact "error" he's getting is because he's
upgraded to Java 1.5 and has to do with generis. I'm guessing his code looks
like this:

List myResults = new LinkedList();

where the warning has to do with the fact that Sun strongly recommends
you use the generic version of the collection API, so he should change it
to:

List<ArrayOfComplexNumbers> myResults = new
LinkedList<ArrayOfComplexNumbers>();

Except that one of the elements in that list is a boolean, so really he
needs to put:

List<Object> myResults = new LinkedList<Object>();

In another branch of this thread, I pointed out that there are some
design problems with his code, and he should probably spend the time to fix
those rather than continue to just hack away at his current implementation
until it "just works". Especially since he says he is a perfectionist.

- Oliver
 
S

Stefan Ram

BemusedByQM said:
So my question is how do I return two 3-dimensional arrays (each holding
BigDecimal type entries), and a boolean type variable from a java method???

To return with the appropriate static types, a corresponding
class might be defined (as others already wrote).

The following example tries to deal with the general question,
how to return multiple values. "example1" does use Java only,
while "example2" uses an additional preprocessor.

$define RETURN return multi($1)

$define MULTI java.lang.Object[]

public class Main
{
public java.lang.Object[] multi( java.lang.Object ... it )
{ return it; }

public java.lang.Object[] example1()
{ return multi( System.in, System.out ); }

public MULTI example2()
{ RETURN( System.in, System.out ); }

public static void main( final String[] _ )
{ java.lang.System.out.println( "2005-08-16T00:44:26+02:00" ); }}
 
R

Roedy Green

So my question is how do I return two 3-dimensional arrays (each holding
BigDecimal type entries), and a boolean type variable from a java method???

The klutz way to do it is

return new Object[] { three1, three3, new Boolean( whether) };

The proper way to do is in define a new Object type:

new class Pair
{
ThreeD first;
ThreeD second;
boolean whether;
// various constructors getters, setters etc.

}
 
R

Roedy Green

I think the big problem actually is that the Java programming language
wasn't designed in such a way so as to make it easy to write methods which
return multiple return values.

If you drew a Java program showing data flow, you would see arrows
converging on each method call. Each method has many inputs and only
one output.

If you come from background such as Forth, this seems unduly
restrictive. Why should a method not have multiple outputs?

I saw one way of adding the notion to a Java-like language using
tuples. A tuple is just a group of items, not necessarily the same
type e.g. the inputs to a method. The outputs are handled the same
way.
 
B

BemusedByQM

Oliver Wong said:
BemusedByQM said:
Yes one of my programs is a math program, which carries out an 'LU
decomposition' upon a matrix which has been supplied by the user (for
matrix here read 'array' - a matrix is simply a math term for a 2D array
of numbers). The decomposition returns three matrices upon completing
the routine - a P-matrix, L-matrix, and a U-matrix.
I think I said in an earlier post that the arrays (or matrices) were 3D -
they are and the reason they are 3D and not 2 is because they carry
'complex numbers' which require a second field to represent them.

Sometimes though, under certain conditions, the P-matrix is not strictly
required, so a boolean value is also returned to 'flag' whether the
P-matrix is needed or not.

So, I am in the position of having to return three 3-dimensional arrays
and a boolean.

Okay, so first of all, I recommend you create a class to represent
complex numbers, something like:

public class ComplexNumber {
public double i, r;
}

should work; you might want to add convenience functions (getting the
square root of a complex number, for example) to the class.

Then you can create a class which represents the results (is there a name
of the set { P-matrix, L-matrix, U-matrix}?) I'll call the class "result"
because I don't know the terminology, but maybe you can come up with a
better name.

public class Result {
private ComplexNumber[][] pMatrix, lMatrix, uMatrix;

ComplexNumber[][] getPMatrix() {
return this.pMatrix;
}

ComplexNumber[][] getLMatrix() {
return this.lMatrix;
}

ComplexNumber[][] getUMatrix() {
return this.uMatrix;
}

boolean isPMatrixPresent() {
return pMatrix != null;
}
}

The last method is a common idiom in Java. Rather than returning a flag to
indicate whether or not the 3rd matrix is there, set pMatrix to null. Then
you can test whether pMatrix is equal to null or not to determine whether
or not it's there.

Yes, thats a rather elegant way of expressing the whole thing i must say.
thanks for that
 
J

Jeremy Watts

BemusedByQM said:
Daniel Dyer said:
class DandyerWrapper{
private BigDecimal[][][] array1;
private BigDecimal[][][] array2;
private BigDecimal[][][] array3;
private Boolean booleanName;
}

add setters and getters and return List<DandyerWrapper>

But I won't be offended if you choose not to name it after me.

Dan.

thanks for that daniel, most obliged :)


Hello Daniel,

Hope you dont mind helping me out a bit further. I have defined the class
:-

class returnWrapper{
private BigDecimal[][][] Pmatrix;
private BigDecimal[][][] Lmatrix;
private BigDecimal[][][] Umatrix;
private Boolean LDMexists;
}


But still am a bit confused as to what comes next :) I need to define
the sizes of the P,L & U matrices, and also the initial state of the
boolean, which is true in this case. So do I do these initialisations
within the class? And if so how are these done?

Bit confused as to 'getters' and 'setters', still a java newbie I'm afraid.
So once the arrays and boolean have been declared within the class wrapper,
how are they then referred to outside of it?


Thanks
 
S

Stefan Schulz

I'm relatively confident the exact "error" he's getting is because he's
upgraded to Java 1.5 and has to do with generis. I'm guessing his code looks
like this:

List myResults = new LinkedList();

List <Object> myResults = new LinkedList<Object>();

This should clear up the warning. Now you declare a list of positively
anything, even mixed types.
 
R

Robert Klemme

Daniel said:
class DandyerWrapper{
private BigDecimal[][][] array1;
private BigDecimal[][][] array2;
private BigDecimal[][][] array3;
private Boolean booleanName;
}

add setters and getters and return List<DandyerWrapper>

But I won't be offended if you choose not to name it after me.

Dan.

Just to throw in some completely different approach: since the method
seems to be doing quite complex stuff what about applying command pattern?
You create a class for this operation that has properties for input
parameters, an execute method and properties for results. That way you
can easily handle complex results.

Kind regards

robert
 
J

Jeremy Watts

Stefan Schulz said:
List <Object> myResults = new LinkedList<Object>();

This should clear up the warning. Now you declare a list of positively
anything, even mixed types.

Now why didnt I think of that...?? Or anyone else for that matter... :)
The simplest and most obvious solutions are often the ones that strike you
last....
 
A

Andrew Thompson

Now why didnt I think of that...?? Or anyone else for that matter... :)

Others did. They just thought it better not to mention,
at least until you understood that this collection of
data was actually a class in its own right.

(sigh)
 
O

Oliver Wong

Jeremy Watts said:
class returnWrapper{
private BigDecimal[][][] Pmatrix;
private BigDecimal[][][] Lmatrix;
private BigDecimal[][][] Umatrix;
private Boolean LDMexists;
}


But still am a bit confused as to what comes next :) I need to define
the sizes of the P,L & U matrices, and also the initial state of the
boolean, which is true in this case. So do I do these initialisations
within the class? And if so how are these done?

You write a special method called a constructor. A Constructor must have the
same name as the class it's defined in. I'll modify the code above as is;
if you choose to use my suggestions for a complex number class and such, you
can probably figure out the changes you need to make from the following
example; if not, feel free to post again.

class returnWrapper {
private BigDecimal[][][] Pmatrix;
private BigDecimal[][][] Lmatrix;
private BigDecimal[][][] Umatrix;
private Boolean LDMexists;

public returnWrapper() {
this.Pmatrix = new BigDecimal[3][3][3];
this.Lmatrix = new BigDecimal[3][3][3];
this.Umatrix = new BigDecimal[3][3][3];
this.LDMexists = true;
}
}

you would then actually "create" an instance of this class using the "new"
keyword:

returnWrapper anActualInstanceOfTheReturnWrapperClass = new returnWrapper();
Bit confused as to 'getters' and 'setters', still a java newbie I'm
afraid. So once the arrays and boolean have been declared within the class
wrapper, how are they then referred to outside of it?

when you declare fields (fields are variables inside of objects) as being
private, that means only methods declared within the same class can access
them. 'getters' and 'setters' are just a name for methods whose only purpose
is to get the value inside of fields. You could add getters and setters like
this:

class returnWrapper {
private BigDecimal[][][] Pmatrix;
// etc. for the other matrices
private Boolean LDMexists;

public BigDecimal[][][] getPMatrix() {
return this.PMatrix;
}

public void setPMatrix(BigDecimal[][][] newValue) {
this.PMatrix = newValue;
}

public Boolean getLDMexists() {
return this.LDMexists;
}

public void setLDMexists(Boolean newValue) {
this.LDMExists = newValue;
}
}

or you might want to do it like this:

class returnWrapper {
private BigDecimal[][][] Pmatrix;
// etc. for the other matrices
private Boolean LDMexists;

public BigDecimal[][][] getPMatrix() {
return this.PMatrix;
}

public void setPMatrix(BigDecimal newValue, int x, int y, int z) {
this.PMatrix[x][y][z] = newValue;
}

public Boolean getLDMexists() {
return this.LDMexists;
}

public void setLDMexists() {
this.LDMExists = true;
}
}

- Oliver
 
J

Jeremy Watts

Oliver Wong said:
Jeremy Watts said:
class returnWrapper{
private BigDecimal[][][] Pmatrix;
private BigDecimal[][][] Lmatrix;
private BigDecimal[][][] Umatrix;
private Boolean LDMexists;
}


But still am a bit confused as to what comes next :) I need to define
the sizes of the P,L & U matrices, and also the initial state of the
boolean, which is true in this case. So do I do these initialisations
within the class? And if so how are these done?

You write a special method called a constructor. A Constructor must have
the same name as the class it's defined in. I'll modify the code above as
is; if you choose to use my suggestions for a complex number class and
such, you can probably figure out the changes you need to make from the
following example; if not, feel free to post again.

class returnWrapper {
private BigDecimal[][][] Pmatrix;
private BigDecimal[][][] Lmatrix;
private BigDecimal[][][] Umatrix;
private Boolean LDMexists;

public returnWrapper() {
this.Pmatrix = new BigDecimal[3][3][3];
this.Lmatrix = new BigDecimal[3][3][3];
this.Umatrix = new BigDecimal[3][3][3];
this.LDMexists = true;
}
}

you would then actually "create" an instance of this class using the "new"
keyword:

returnWrapper anActualInstanceOfTheReturnWrapperClass = new
returnWrapper();
Bit confused as to 'getters' and 'setters', still a java newbie I'm
afraid. So once the arrays and boolean have been declared within the
class wrapper, how are they then referred to outside of it?

when you declare fields (fields are variables inside of objects) as being
private, that means only methods declared within the same class can access
them. 'getters' and 'setters' are just a name for methods whose only
purpose is to get the value inside of fields. You could add getters and
setters like this:

class returnWrapper {
private BigDecimal[][][] Pmatrix;
// etc. for the other matrices
private Boolean LDMexists;

public BigDecimal[][][] getPMatrix() {
return this.PMatrix;
}

public void setPMatrix(BigDecimal[][][] newValue) {
this.PMatrix = newValue;
}

public Boolean getLDMexists() {
return this.LDMexists;
}

public void setLDMexists(Boolean newValue) {
this.LDMExists = newValue;
}
}

or you might want to do it like this:

class returnWrapper {
private BigDecimal[][][] Pmatrix;
// etc. for the other matrices
private Boolean LDMexists;

public BigDecimal[][][] getPMatrix() {
return this.PMatrix;
}

public void setPMatrix(BigDecimal newValue, int x, int y, int z) {
this.PMatrix[x][y][z] = newValue;
}

public Boolean getLDMexists() {
return this.LDMexists;
}

public void setLDMexists() {
this.LDMExists = true;
}
}

- Oliver

Oliver thanks for that, and I've saved your post for future reference. But
I've decided to solve this incredibly easily, just by simply inserting
 
A

Andrew Thompson

On Tue, 16 Aug 2005 14:48:48 GMT, Jeremy Watts wrote:

[snip Oliver's advice]
I've saved your post for future reference.

Yes, but.. you did not need to post *100* lines of Oliver's
text back at us. We had already just seen it.

Please trim most material when replying in future,
leaving just enough quoted material to provide a
context for what you are replying to.
 
S

Stefan Schulz

Others did. They just thought it better not to mention,
at least until you understood that this collection of
data was actually a class in its own right.

Once in a while, i do feel charitable. ;) I promise i'll be good for a
while now
 
R

Raymond DeCampo

Oliver said:
Okay, so first of all, I recommend you create a class to represent
complex numbers, something like:

public class ComplexNumber {
public double i, r;
}

Might I suggest not using a variable called "i" in a class representing
complex numbers? It would be the equivalent of having a variable named
"0" or "2" (at least to the people using it, if not the compiler and JVM).

Ray
 
O

Oliver Wong

Raymond DeCampo said:
Might I suggest not using a variable called "i" in a class representing
complex numbers? It would be the equivalent of having a variable named
"0" or "2" (at least to the people using it, if not the compiler and JVM).

I was thinking "imaginary component" and "real component". Haven't done
much math with complex numbers though so I don't know what, if any, standard
variable names are used there.

- Oliver
 
R

Raymond DeCampo

Oliver said:
I was thinking "imaginary component" and "real component". Haven't done
much math with complex numbers though so I don't know what, if any, standard
variable names are used there.

I understand where you were coming from when you picked the names and
that was not bad reasoning. The point that I am making is that in the
set of complex numbers, i is a literal number like 0 or 2. So it would
be potentially confusing for people familiar with this (common) notation.

For example, if someone were to ask you what complex number the class
represented, the most natural answer would be r + ii, where the two i-s
mean different things.

Personally I would probably use x and y to emphasize the relationship
with the complex plane and the (x,y) coordinate system. (In this case
the complex number x + iy is represented.)

Ray
 

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,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top