0

I'm looking for a way to store different data types in one fixed length collection so I can set/get elements by index. What's the best way to go about this? Thanks!

EDIT: Should this work?

private List t=new ArrayList();
t.set(2,"test");

I get this: java.lang.IndexOutOfBoundsException: Index: 2, Size: 0

cronoklee
  • 6,482
  • 9
  • 52
  • 80
  • 6
    What's wrong with a normal array? – Sophie Alpert Apr 03 '11 at 23:39
  • 1
    Whether or not you can do this is not as important as that having an array hold different types of objects is in general a **bad idea** . Why do you feel that your program must do this? Perhaps what you really want is to create a new class to hold your various objects and have an array or ArrayList of objects of this class. – Hovercraft Full Of Eels Apr 03 '11 at 23:44
  • Thanks @Ben / @Hovercraft. I need to store dynamically timed data for a few milliseconds. I'm using the generic array as a buffer to gather some data from a live stream of audio. Creating a class is an option but its just a few elements that are changing a few hundred times a second. Is a class really the best way to go? – cronoklee Apr 03 '11 at 23:56
  • @cronoklee - yes it is. It will be just as fast ... and probably faster. If you are concerned about the "problem" of allocating lots of objects, just make the class mutable and use setters to update an instance that you keep ... just like you would an array. – Stephen C Apr 04 '11 at 00:06
  • Maybe all you need is a byte buffer of some sort, not an array. – Hovercraft Full Of Eels Apr 04 '11 at 00:37
  • @Hovercraft - I don't think so. My understanding is that array / list / object is purely internal to the application. No need to serialize or deserialize, or anything like that. – Stephen C Apr 04 '11 at 01:07
  • @Stephen: I think that I don't understand your post as I don't recall mentioning serialization. My take is that he has to read in and buffer data from a live audio stream, and if it is coming in as pure bytes, why not create a buffer to hold them? – Hovercraft Full Of Eels Apr 04 '11 at 01:11
  • But he doesn't want to hold bytes or things encoded as bytes. He wants to hold things of different types. – Stephen C Apr 04 '11 at 11:24

4 Answers4

2

Should this work?

private List t=new ArrayList();
t.set(2,"test");

No it shouldn't. A List doesn't automagically grow if you call set with a position that is beyond the end of the list. (See the javadoc.)

If you want to do that kind of thing you have to fill the List with null elements first; e.g.

private List t=new ArrayList();
for (int i = 0; i < LIMIT; i++) {
    t.add(null);
}
...
t.set(2,"test");

But I'd also like to reiterate the point that various other answers have made. You should write a class and do this in a type-safe fashion. Stuffing things into an Object[] or List<Object> ... and hoping that you get the indexes and types right ... gives you fragile code. It is bad practice.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
0

You can do such a thing with List. It has get/set methods by index. I don't see why fixed length is important here.

You can always encapsulate precisely the behavior you want in a class of your own devising. You can have a backing array to manage it for you, but you'll have to do all the work yourself.

duffymo
  • 305,152
  • 44
  • 369
  • 561
0

Can't you make an array of Objects? Which means everything except the primitive types (int, char, boolean, etc.); if you want to store them you have to wrap them in their corresponding Object Wrapper classes (Integer, Character, Boolean, etc.) So like:

mult_type[0] = "A String";
mult_type[1] = new Integer(42);
mult_type[2] = new Long(7149994000);

and so on. Although mult_type[i] is an Object by definition, the entry stored there can be any subclass of Object. When you want to retrieve them, you can examine them to find out what class they actually belong to. There are a couple of ways to do this, one is to use the "instanceof" operator like so:

if (mult_type[i] instanceof Integer) {
Integer anInteger = (Integer)mult_type[i];
int anInt = anInteger.intValue();
}

Notice that you have to "cast" the object to its actual class as you retrieve it.

Benjamin
  • 2,718
  • 5
  • 21
  • 20
0

You need a Javabean. Create a class which represents the whole picture of all those different properties together. E.g. an User with id, name, gender, dateOfBirth, active, etc.

public class User {
    private Long id;
    private String name;
    private Gender gender;
    private Date dateOfBirth;
    private Boolean active;

    // Add/generate c'tor(s)/getters/setters/equals and other boilerplate.
}

This way you end up with a clear and reuseable abstraction.

User user = new User();
user.setName("John Doe");
user.setGender(Gender.MALE);
// ...

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • This is cool but seems a bit overkill for my current needs. I only need to store data for a few milliseconds. I'm using the generic array as a buffer to gather some data from a live stream of audio. – cronoklee Apr 03 '11 at 23:48
  • @cronoklee - it is is not overkill. It is the **correct** way to do it it Java. Stuffing random things into a `Object[]` is a recipe for fragile code. – Stephen C Apr 03 '11 at 23:55
  • @cronoklee: Did you measure it? I'd prefer clear, self-documenting and thus well maintainable code over ugly code. – BalusC Apr 03 '11 at 23:55
  • no didnt measure it - Its just a lot of code for such a simple idea and I'm not so familiar with iterating/working with class objects etc. I want to concat the whole object to a string intermittently. I might just concat it every iteration and store it in a string array but I was hoping to save processor power since this is run at audio sample rate – cronoklee Apr 04 '11 at 00:06