Problems adding Objects to an ArrayList

M

Marcel.luchi

Hi there, please can anyone help me?

Im having troubles when adding objects to an ArrayList.

This is the Code:

public ArrayList <Especie> parse (ArrayList <String> vec) {
ArrayList <Especie> individuos = new ArrayList <Especie>
();
int inter[] = new int [17];
int vecsize = vec.size ();
for (int i = 0; i < vecsize; i++) {
String carac[] = vec.get (i).toString ().split (",") ;
for (int j=0; j<17; j++) {
inter[j] = Integer.parseInt (carac[j+1]);
}
individuos.add (new Especie (inter));
}
for(Especie e: individuos){
for(int i=0; i<17; i++){
}
}
return individuos;
}

What happens is that the Objects Especie are being created correctly,
but when i add it to the ArrayList individuos, the last created
Especie is added N times to the ArrayList.

I think the proplem is in the line
individuos.add(new Especie(inter));
but dun know what is wrong in it.

Tnx.

Marcel Luchi Marchi
 
C

Chris Dollin

Marcel.luchi said:
Hi there, please can anyone help me?

Im having troubles when adding objects to an ArrayList.

This is the Code:

public ArrayList <Especie> parse (ArrayList <String> vec) {
ArrayList <Especie> individuos = new ArrayList <Especie>
();
int inter[] = new int [17];
int vecsize = vec.size ();
for (int i = 0; i < vecsize; i++) {
String carac[] = vec.get (i).toString ().split (",") ;

Why not

for (String elem: vec) {
String [] carac = elem.split( "," );
for (int j=0; j<17; j++) {
inter[j] = Integer.parseInt (carac[j+1]);
}
individuos.add (new Especie (inter));

Each new `Especie` will have /the same/ `inter` array passed to it.

If all you do is copy the reference to the array, then they'll all
share the same array, so they'll all look like the most recent
update.
 
P

Patricia Shanahan

Marcel.luchi said:
Hi there, please can anyone help me?

Im having troubles when adding objects to an ArrayList.

This is the Code:

public ArrayList <Especie> parse (ArrayList <String> vec) {
ArrayList <Especie> individuos = new ArrayList <Especie>
();
int inter[] = new int [17];
int vecsize = vec.size ();
for (int i = 0; i < vecsize; i++) {
String carac[] = vec.get (i).toString ().split (",") ;
for (int j=0; j<17; j++) {
inter[j] = Integer.parseInt (carac[j+1]);
}
individuos.add (new Especie (inter));
}
for(Especie e: individuos){
for(int i=0; i<17; i++){
}
}
return individuos;
}

What happens is that the Objects Especie are being created correctly,
but when i add it to the ArrayList individuos, the last created
Especie is added N times to the ArrayList.

I think the proplem is in the line
individuos.add(new Especie(inter));
but dun know what is wrong in it.

There is nothing wrong with it. The problem is with the handling of
inter. You are adding distinct Especie references, but all instances are
created referencing the same instance of inter.

You first need to decide on the rules for the constructor parameter. Is
the caller allowed to change the contents of the array after the
constructor call?

If yes, then the Especie constructor needs to make its own copy of the
array contents before returning, e.g. by creating a new array and using
System.arraycopy.

If no, then the code you quoted should create a new array instance for
each Especie creation.

Patricia
 
D

Daniel Pitts

Marcel.luchi said:
Hi there, please can anyone help me?

Im having troubles when adding objects to an ArrayList.

This is the Code:

public ArrayList <Especie> parse (ArrayList <String> vec) {
ArrayList <Especie> individuos = new ArrayList <Especie>
();
int inter[] = new int [17];
int vecsize = vec.size ();
for (int i = 0; i < vecsize; i++) {
String carac[] = vec.get (i).toString ().split (",") ;
for (int j=0; j<17; j++) {
inter[j] = Integer.parseInt (carac[j+1]);
}
individuos.add (new Especie (inter));
}
for(Especie e: individuos){
for(int i=0; i<17; i++){
}
}
return individuos;
}

What happens is that the Objects Especie are being created correctly,
but when i add it to the ArrayList individuos, the last created
Especie is added N times to the ArrayList.

I think the proplem is in the line
individuos.add(new Especie(inter));
but dun know what is wrong in it.

Tnx.

Marcel Luchi Marchi
Actually, it looks like you pass in the same inter object to all the
especie objects.
you need to have int inter[] = new int[17] inside your vectsize loop.

Other tips:
When posting code on usenet, try to keep tab size to between 2 and 4 spaces.
Array syntax is better expressed "int[] inter" in Java.

Unless you absolutely need to, don't declare return types or parameters
as ArrayList, or other specialized collections, use the most generic
interface that makes sense.

Also, use the for each construct when appropriate.

public List<Especie> parse(Collection<String> strings) {
List<Especie> parsed = new ArrayList<Especie>(strings.size());
for (String string: strings) {
int[] values = new int[17];
String[] tokens = string.split(",");
for (int i = 0; i < 17; ++i) {
values = Integer.parseInt(tokens[i+1]);
}
parsed.add(new Especie(values));
}
return parsed;
}

Further design suggestions:

This assumes good form on your input. That is especially dangerous when
dealing with String input. You might verify that string.split(",")
actually returns 18 tokens, or instead of passing in an int[], use a
List<Integer>, which allows for different sized inputs.

It might also make sense to put the parsing logic into Especie itself.
Create what is called a factory method:
class Especie {
public static Especie parse(String string) {
String[] tokens = string.split(",");
if (tokens.length < 18) {
throw new IllegalArgumentException("Not enough commas");
}
int[] values = new int[17];
for (int i = 0; i < 17; ++i) {
values = Integer.parseInt(tokens[i+1]);
}
return new Especie(values);
}
}

Then your other parse loop becomes:

public List<Especie> parse(Collection<String> strings) {
List<Especie> parsed = new ArrayList<Especie>(strings.size());
for (String string: strings) {
parsed.add(Especie.parse(string));
}
return parsed;
}

Hope at least some of these suggestions help you out.
 
D

Daniel Pitts

Roedy said:
the problem is type erasure. Especie becomes Object at run time.
There in no constructor Object ( inter );

see http://mindprod.com/jgloss/generics.html

to create new objects of a variable type requires some fancy footwork,
e.g. by passing a class object and using newInstance or reflection.
Sorry Roedy, this time you've made a mistake.

Especie is a concrete type in the OPs code. It just doesn't look like it
because of his (her?) formatting. Also, the stated problem was that it
appeared that the same object was in the list multiple times.
 
L

Lasse Reichstein Nielsen

Marcel.luchi said:
int inter[] = new int [17];

Array created here. This happens only once.
int vecsize = vec.size ();
for (int i = 0; i < vecsize; i++) {
String carac[] = vec.get (i).toString ().split (",") ;
for (int j=0; j<17; j++) {
inter[j] = Integer.parseInt (carac[j+1]);

Array updated for each loop iteration.
}
individuos.add (new Especie (inter));

Same array passed to all constructors. The array is changed
after the object is created.
} ....
What happens is that the Objects Especie are being created correctly,
but when i add it to the ArrayList individuos, the last created
Especie is added N times to the ArrayList.

Probably not. The Especie objects are different, but my guess is that
the Especie(int[]) constructor *stores* the int array.
Then the next iteration changes the values of that int array, and
alos passes it to a new constructor.

Try copying (e.g., cloning) the array in the constructor instead of
storing the original argument.
I think the proplem is in the line
individuos.add(new Especie(inter));
but dun know what is wrong in it.

All that is wrong is that the "inter" array is the same array for all
calls. The data in it will eventually be the data set by the last
iteration.

/L
 
D

Daniel Pitts

Roedy said:
oops. Never mind. It sounded like a placeholder name, which mislead
me.
I was mislead briefly at first too. Style and naming do have an impact :)
 

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

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,276
Latest member
Sawatmakal

Latest Threads

Top