Java collections

T

tim

I've create a small program that loops through a database table and
adds columns of the retrieved row to a collection.
For some reason, the Collection.add statement seems to be changing all
of the data to the contents of the last row processed.
Any Idea what would cause this? I am running it through the debug mode
of Eclipse and can see it happen during the add statement.

Here is a snippet of the code.

while (rset.next()) {
Cust.setCUST_NUMBER(rset.getInt(1));
Cust.setLAST_NAME(rset.getString(2));
Cust.setFIRST_NAME(rset.getString(3));
Cust.setSEX(rset.getString(4));
Cust.setCITY(rset.getString(5));
CustomerCollection.add(Cust);
}
 
V

Vova Reznik

I've create a small program that loops through a database table and
adds columns of the retrieved row to a collection.
For some reason, the Collection.add statement seems to be changing all
of the data to the contents of the last row processed.
Any Idea what would cause this? I am running it through the debug mode
of Eclipse and can see it happen during the add statement.

Here is a snippet of the code.

while (rset.next()) {

Customer Cust = new Customer();
 
T

tim

Great. That works.
What I don't understand is that when I printed out the values of the
Cust object, like FIRST_NAME, it was different each time through the
loop. So I was adding the different field values to the collection but
it went back and changed the FIRST_NAME values already added to the
collection to the most recent value. I can't see why the values already
added were changed.
Any explanation?
 
T

tim

The only thing I can think of is the collection points to the Cust
object and when the Cust object changes, all occurences in the
collection change as well since they are all pointing to the same
object.
But how does adding a new Customer each time help? Do the old ones hang
around being pointed to by the various occurences of the collection?
 
A

Arvind

The only thing I can think of is the collection points to the Cust
object and when the Cust object changes, all occurences in the
collection change as well since they are all pointing to the same
object.

You guessed right
But how does adding a new Customer each time help? Do the old ones hang
around being pointed to by the various occurences of the collection?

Customer cust = new Customer, effectively means that you now have a new
object and new set of values.

If you did not do a new Customer(), then the equivalent in a database
would be a single row of data - so think of what would happen in that
case ! - you keep overwriting the same row - and hence you will be left
with last row of data only.

When you do a new Customer(), you are informing the collection that it
is new object which has different set of values. database equivalent
being, you have created a new row in the table
 
T

tim

So then, each row of the collection would automatically point to the
location in memory for the Customer that was referenced by the Customer
variable when the add was done. And the garbage collection would know
not to destroy the old Customers that are being referenced by previous
rows of the collection, even though they are no longer the location in
memory referenced by the Customer variable.
 
E

Eric Sosman

So then, each row of the collection would automatically point to the
location in memory for the Customer that was referenced by the Customer
variable when the add was done. And the garbage collection would know
not to destroy the old Customers that are being referenced by previous
rows of the collection, even though they are no longer the location in
memory referenced by the Customer variable.

It seems you're still a little bit confused, so let
me try to hammer home a point that I think will clear
things up for you. Chisel the following on a suitable
slab of marble and hang it on the wall at your workplace:

VARIABLES ARE NOT OBJECTS

Now, what on Earth could I possibly mean by this
nonsense? Of course, variables are (or can be) objects!
When I write `int i' it means "the variable i is an int,"
so when I write `Customer c' it must mean "the variable c
is a Customer." I must be wacko to think otherwise, right?

Well, no: Analogy is not proof, and two syntactic forms
that look similar don't necessarily mean the same thing.
`Customer c' means that c is a *reference* to a Customer,
not that c *is* a Customer. The Customer instance itself
lives somewhere out in hyperspace, and c holds a reference
to it. When you do

Customer c1 = new Customer("Tim");
Customer c2 = c1;

.... there is only one Customer instance in play, and both
reference variables c1 and c2 point to it. If the above
is followed by

c2 = null;

this does not destroy the Customer instance, nor influence
it in any way: the instance lives on, even if one of the
many references to it has disappeared. (Write your phone
number on a piece of paper, then burn the paper: Did your
phone catch fire?)

Now: When you call collection.add(c1), what manner of
argument does the add() method receive? You're catching
on: it receives a copy of the reference c1, so the argument
is yet another reference to that lonely Customer instance.
What do you suppose add() puts into the collection? Yes,
it salts away a copy of its argument, that is, a reference
to that very same Customer. After add() returns, there are
two references to the Customer in your program: the variable
c1 and another one somewhere in the colleciton. (c2, you'll
recall, has been set to null and no longer refers to the
Customer.)

So:

- Making lots of copies of a reference doesn't make
lots of copies of the Customer it refers to. (Photocopying
your phone number doesn't clone your phone.)

- If you make a change to the Customer, that change
becomes apparent via all the references. (Change the "I'm
busy now" message on your phone, and all callers will hear
the new message even if they got your number from an old
piece of paper.)

- Any reference to a particular Customer is just as good
as any other; they all work identically. (It doesn't matter
which piece of paper somebody reads to find your phone number;
your phone rings anyhow.)

The last point also applies to the garbage collector: as
long as at least one reference to the Customer survives, Java
knows that the Customer might still be used and therefore will
not treat it as garbage. Since all references are equivalent,
a reference inside a collection is every bit as effective as
an ordinary reference variable: as long as the collection still
refers to the Customer (and as long as the collection itself
remains accessible), the Customer is accessible and Java won't
discard it.

Concentrate on the distinction between references and
instances, and I think much of your confusion will disappear.
 
R

Rhino

Eric Sosman said:
It seems you're still a little bit confused, so let
me try to hammer home a point that I think will clear
things up for you. Chisel the following on a suitable
slab of marble and hang it on the wall at your workplace:

VARIABLES ARE NOT OBJECTS

Now, what on Earth could I possibly mean by this
nonsense? Of course, variables are (or can be) objects!
When I write `int i' it means "the variable i is an int,"
so when I write `Customer c' it must mean "the variable c
is a Customer." I must be wacko to think otherwise, right?

Well, no: Analogy is not proof, and two syntactic forms
that look similar don't necessarily mean the same thing.
`Customer c' means that c is a *reference* to a Customer,
not that c *is* a Customer. The Customer instance itself
lives somewhere out in hyperspace, and c holds a reference
to it. When you do

Customer c1 = new Customer("Tim");
Customer c2 = c1;

... there is only one Customer instance in play, and both
reference variables c1 and c2 point to it. If the above
is followed by

c2 = null;

this does not destroy the Customer instance, nor influence
it in any way: the instance lives on, even if one of the
many references to it has disappeared. (Write your phone
number on a piece of paper, then burn the paper: Did your
phone catch fire?)

Now: When you call collection.add(c1), what manner of
argument does the add() method receive? You're catching
on: it receives a copy of the reference c1, so the argument
is yet another reference to that lonely Customer instance.
What do you suppose add() puts into the collection? Yes,
it salts away a copy of its argument, that is, a reference
to that very same Customer. After add() returns, there are
two references to the Customer in your program: the variable
c1 and another one somewhere in the colleciton. (c2, you'll
recall, has been set to null and no longer refers to the
Customer.)

So:

- Making lots of copies of a reference doesn't make
lots of copies of the Customer it refers to. (Photocopying
your phone number doesn't clone your phone.)

- If you make a change to the Customer, that change
becomes apparent via all the references. (Change the "I'm
busy now" message on your phone, and all callers will hear
the new message even if they got your number from an old
piece of paper.)

- Any reference to a particular Customer is just as good
as any other; they all work identically. (It doesn't matter
which piece of paper somebody reads to find your phone number;
your phone rings anyhow.)

The last point also applies to the garbage collector: as
long as at least one reference to the Customer survives, Java
knows that the Customer might still be used and therefore will
not treat it as garbage. Since all references are equivalent,
a reference inside a collection is every bit as effective as
an ordinary reference variable: as long as the collection still
refers to the Customer (and as long as the collection itself
remains accessible), the Customer is accessible and Java won't
discard it.

Concentrate on the distinction between references and
instances, and I think much of your confusion will disappear.
Nicely explained, Eric! If you're not a teacher or a tech writer, you
_could_ be :)
 
B

Bjorn Abelli

...
Isn't that what I said?

Almost, but just almost.

You said:

"So then, each row of the collection..."

A Collection has not necessarily the notion of "rows", mostly not. It could
be used as a metaphor, but metaphors are easily misunderstood in these
forums as "facts". A better phrase would be "each element in the
collection".

"...would automatically point to the location in
memory for the Customer that was referenced
by the Customer variable when the add was done."

Here's where you start to slide, and the point that Eric made, that you need
to look closer to the difference between "references" and "instances", and I
would like to add; their difference towards "variables".

Compare these two examples on how to add a reference to a Collection:

Customer c = new Customer();
CustomerCollection.add(c);

....or...

CustomerCollection.add(new Customer());

In the first case the reference to the instance is held by the variable c.
That reference gets copied into the collection.

In the second case, there's no variable as in the first place, but the
reference of the new Customer gets copied into the Collection anyway.

"And the garbage collection would know not to
destroy the old Customers that are being
referenced by previous rows of the collection,
even though they are no longer the location in
memory referenced by the Customer variable."

As I said, a reference is a reference, and a variable is a variable. Don't
confuse them with each other.

A variable can hold the reference to one instance.

A Collection can hold references to several instances.

The GC don't come into play until there are no reachable references left,
whether from variables or otherwise.

// Bjorn A



Inviato da X-Privat.Org - Registrazione gratuita http://www.x-privat.org/join.php
 
T

tim

Well my terminology is not the best but I think I was getting at the
same things as you two were.

Thanks for the clarification anyway. If I hear these things enough,
they may actually sink in.
 
T

tim

What is the reference to an instance of an object in the form of? A
memory location or something else?
 
R

Robert Klemme

What is the reference to an instance of an object in the form of? A
memory location or something else?

It's more complicated than that in Java but if it helps your
understanding you can stick to that. Basically it's enough to remember
that a reference to an instance uniquely identifies that instance.

Kind regards

robert
 
C

Chris Uppal

What is the reference to an instance of an object in the form of? A
memory location or something else?

It will really help you both to understand, and to think about, things if you
can get the terminology correct from the start. (It'll also help you
communicate with other people, but that's a secondary benefit). So, what I
think you are asking is:

What is the form of a reference to an object ?
or
What is the form of a reference to an instance of a class ?

The two are almost identical in meaning, but it's /important/ to keep classes
and objects separate in your mind.

As to your question itself, the technically correct answer is that you don't
know and have no way of finding out. It's an internal matter to the JVM -- it
could (in principle) even use different physical forms for object references on
the stack (local variables), references passed between method calls (also on
the stack), and object references stored in arrays or in other objects'
instance fields (in the heap). Ultimately it's an invisible implementation
detail.

A more satisfying answer, I imagine, is that on any mainstream JVM you are
likely to use[*] the reference is represented physically as a 32- or 64-bit
"pointer" holding the object's address in memory.

([*] with the caveat that I have no idea how they are implemented on JVMs
intended for resource-constrained devices -- I can easily imagine a non-pointer
representation being preferred in such cases)

BTW, it's not just an academic point. Many GCed languages don't use a direct
pointer to implement object references (and I can even think of a couple JVM
implementations that don't -- not mainstream, though).

-- chris
 

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,768
Messages
2,569,574
Members
45,049
Latest member
Allen00Reed

Latest Threads

Top