What is the best (proper?) way of returning different types of values

I'm trying to return multiple different types of values from a method. I'm having trouble correctly assigning vectors when they are returned. Strings, booleans, and other objects are ok. Vector cause me unchecked conversion problems.

So the method AND main program has:

Vector <String>selectedRun = new Vector<String>();

It returns an object:

return new Object[] {selectedRun, othervalue1, othervalue2};

The method is called like this:

Object[] return_values = Method1(args);

selectedRun = (Vector)return_values[0];

I've tried changing the syntax several times, but so far no luck. What would be the proper way of assigning the Vector in Object[0] to selectedRun?

By searching I found people saying to do these returns using Objects, but is there a better way?

Thanks,

James

[858 byte] By [jpifera] at [2007-11-27 11:05:30]
# 1

Using Object is fine. But you're trying to case an array (many objects) to a Vector (one object). See the problem?

SoulTech2012a at 2007-7-29 13:09:06 > top of Java-index,Java Essentials,Java Programming...
# 2

Unfortunately no I don't see it.

The Vector selectedRun is being stored in the first slot of the object array. The array is then being returned.

Then back in the calling program I'm pulling the Vector out of the first slot in the returned object and assigning it to the Vector selectedRun.

My wording may not be the greatest, but isn't that what I'm doing logically?

Thanks,

James

jpifera at 2007-7-29 13:09:06 > top of Java-index,Java Essentials,Java Programming...
# 3

Needing to return multiple values of differing types smells bad.

Perhaps it's the smell of Class Denial. What are you trying to do?

Would it make sense to define a class to hold the values being returned?

Hippolytea at 2007-7-29 13:09:06 > top of Java-index,Java Essentials,Java Programming...
# 4

I simply have multiple values I need to return that happen to be different types of values. Not being a java expert I guess I don't see the problem, but I'm sure it's too deep of an explanation for a forum thread.

Thanks,

James

jpifera at 2007-7-29 13:09:06 > top of Java-index,Java Essentials,Java Programming...
# 5

import java.util.Vector;

public class Example{

public static void main(String[] newExample){

Object[] result = getter();

System.out.println("1: " + (String)(((Vector)result[0]).get(0)));

System.out.println("2: " + (String)result[1]);

}

public static Object[] getter(){

Vector v = new Vector();

v.add("does this work?");

return new Object[]{v, "of course it does"};

}

}

TuringPesta at 2007-7-29 13:09:06 > top of Java-index,Java Essentials,Java Programming...
# 6

You can use the following to store any types without jdk1.5 complaining about it:

Vector <Object>selectedRun = new Vector<Object>();

The when you read a value out, cast it to the correct type.

However, this is bad design as previously stated. When you retrieve items from the list, you have to know what types and what order those types were put into the list in order to know what to cast them to when retrieved (bad).

Better idea would be like this:

You have these types (classes): Wheel, Bumper, Windshield which are parts of a car. You want to store it in a collection of car parts in a vector. Here's how to do it better than just dump them in a raw vector:

Create these classes:

CarParts

Wheel extends CarParts

Bumper extends CarParts

Windsheld extends CarParts

All the above items have a priceTag (inherited from class CarParts), but each have thier own unique features too. For example: wheel has a diameter, bumper doesnt.

Now you can do:

Vector <CarParts>carItems = new Vector<CarParts>();

carItems.add(new Wheel());

carItems.add(new Bumper());

carItems.add(new Windshield());

Then get the parts:

CarParts item1= carItems.get(0);

System.out.println(item1.getPriceTag());

However, you have to cast item1 to a Wheel type to get its unique features such as wheel.getDiameter();

This is an example of polymorphism. The above probably will not compile cleanly, but you get the idea.

As a general rule, you should avoid storing a collection of different types.

George123a at 2007-7-29 13:09:06 > top of Java-index,Java Essentials,Java Programming...
# 7

> I simply have multiple values I need to return that happen to be different types of values. Not being a java expert I guess I don't see the problem,

Well, you did ask for the best (proper) way to do it. If you choose to ignore it ...

Hippolytea at 2007-7-29 13:09:06 > top of Java-index,Java Essentials,Java Programming...
# 8

The other best way to do it is to redesign so you have several methods, each of which returns exactly one thing.

DrClapa at 2007-7-29 13:09:06 > top of Java-index,Java Essentials,Java Programming...
# 9

I'll look at doing it this way. Never done it before so it'll be a new experience for me. I'll see what heppens.

Thanks.

James

jpifera at 2007-7-29 13:09:06 > top of Java-index,Java Essentials,Java Programming...
# 10

I'm trying to digest the right way to do this, so let me take a step back. I have a bunch of users to process. Each user has a set of information that needs to be managed. Basically, as users are changed, added, or deleted on one side, my program makes those changes at an externally hosted site. I already have a working program, but I was trying to split it up into different classes and streamline things.

So each user has some data:

First Name

Last Name

Title

Phone

etc

Right now I'm reading all the data in from a database connection and storing it in a Vector of Vectors. Then I look at each user and process each user. During this process some of their data gets modified, so I have to make those changes and track the changes for logging purposes.

In order to track changes I'm thinking I might also have:

Title.new

Phone.new

etc

It seems like it would be a good idea to create a class, similar to what you suggested, to store the information for each user. Would that be accurate? Then I would pass that object back and forth between the methods?

I like the idea of the earlier example of item1.getPriceTag() or wheel.getDiameter(), but I don't see in the example how to set this up. So if I needed to the user's title it would be something like: currentUser.getTitle().

Can you point me to an example that might show it more completely?

Do you think I'm on the right track with this?

Thanks,

James

jpifera at 2007-7-29 13:09:06 > top of Java-index,Java Essentials,Java Programming...
# 11

How about a HashSet|Map|Table?

http://java.sun.com/j2se/1.4.2/docs/api/java/util/HashSet.html

Its a collection that lets you retrieve information on Keys.

// keys

static String FIRST_NAME = "first name";

static String EMPLOYEE_NUMBER = "employee number";

Object o = HashSet.get(FIRST_NAME);

TuringPesta at 2007-7-29 13:09:06 > top of Java-index,Java Essentials,Java Programming...
# 12

> Do you think I'm on the right track with this?

Yes. Setting aside the issue of tracking changes, do you think you

could define a basic User class?

Hippolytea at 2007-7-29 13:09:06 > top of Java-index,Java Essentials,Java Programming...
# 13

> How about a HashSet|Map|Table?

But then you lose type checking. What's wrong with defining class User?

Hippolytea at 2007-7-29 13:09:06 > top of Java-index,Java Essentials,Java Programming...
# 14

I think a User class would work fine for me. Can you throw me a quick example with just one or two fields? If you do it this way would it all have to be the same type of fields or could you mix and match the field types? Age is not one of my fields, but could I have a String and an Int in the User class?

How would I create an instance of the class, set, and get information? Apologize, but trying to be thorough.

Thanks,

James

jpifera at 2007-7-29 13:09:06 > top of Java-index,Java Essentials,Java Programming...
# 15

Hippo you contentious b@stard, lol.

There's nothing wrong with defining a user class.

I didnt know whether fields could be added / different between users.

You could always create a UserField class and store those in a Hash

if you wanted to do both.

We're just riffin' here man. We're just riffin', lol.

TuringPesta at 2007-7-29 13:09:10 > top of Java-index,Java Essentials,Java Programming...
# 16

> How would I create an instance of the class, set, and get information? Apologize, but trying to be thorough.

It sounds like you need to learn some basic object-oriented programming.

Hippolytea at 2007-7-29 13:09:10 > top of Java-index,Java Essentials,Java Programming...
# 17

public class UserManager{

public static void main(String[] args){

new UserManager();

}

public UserManager(){

UserInfo user = new UserInfo("bob");

change(user);

System.out.println("User Name: " + user.getFirstName());

}

public void change(UserInfo user){

user.setFirstName("bob is fired");

}

public class UserInfo{

public UserInfo(){};

public UserInfo(String firstName){

this.setFirstName(firstName);

}

public void setFirstName(String firstName){

this.firstName = firstName;

}

public String getFirstName(){

return firstName;

}

private String firstName;

}

TuringPesta at 2007-7-29 13:09:10 > top of Java-index,Java Essentials,Java Programming...
# 18

> I think a User class would work fine for me. Can you

> throw me a quick example with just one or two fields?

> If you do it this way would it all have to be the

> same type of fields or could you mix and match the

> field types? Age is not one of my fields, but could I

> have a String and an Int in the User class?

Yes.

I would suggest objects only however.

Example 1

class User

{

public String name;

public Integer age;

public String address;

}

For updates you return a new version of the above. Only the actual updated items are set (non-null).

If you need to deal with null as a legitimate value then you need an update field for each attribute.

Example2

class User

{

public String name;

public boolean nameChanged;

public Integer age;

public boolean ageChanged;

public String address;

public boolean addressChanged;

}

Examle1 is a case where wrapping in methods provides no additional value. Example2 on the other would provide some value in wrapping the methods.

You can of course avoid Example2 by doing a difference between the original and new one. That is a trade off. But you don't have to deal with a value that changed and then reverted.

Myself with a lot of cases like the above I would generate the code. If you are manually doing this you can save some work and maintain some type checking with something like the following (pseudo code and leaving out some of the stuff from above.)

Example3

class User

{

public void setName(String d)

{

collection.Add("Name", d);

}

public String getName()

{

return collection.Get("Name");

}

private SomeCollection collection = ...;

}

You can use the collection generically to compare for different values. Depending on source and destination you can also populate the collection directly rather than using the set methods. Doing that is very prone to errors however.

jschella at 2007-7-29 13:09:10 > top of Java-index,Java Essentials,Java Programming...
# 19

Thanks for the example and everyone for their suggestions.

James

jpifera at 2007-7-29 13:09:10 > top of Java-index,Java Essentials,Java Programming...