Java Collections

C

Colin Hemmings

Hi there, I was wondering if anybody could possibly help me with my
problem. I have an ArrayList of objects declared as:
ArrayList playerList = new ArrayList();
I have filled the ArrayList with several player objects. My player
objects have a method called 'updateName()', which changes that players
name with the name it is passed.
Currently to change the name of a player in the ArrayList I have to do
the following:
Player tempPlayer = new Player();
tempPlayer = (Player) playerList.get(X);
tempPlayer.updateName("Phillip");

This code works fine, but I was wondering if there is a way of
manipulating the object just using its reference, without having to
retrieve the entire object. For instance, something similar to the
following:
playerList[X].updateName("Phillip");
Similar to the way you access elements in a standard array?

Or is there a better way of accessing elements than what I am doing in
the first example?

Thanks Kindly for any help
 
O

ozgwei

How do you determine which player you'd like to invoke the
updateName(String) method? Or do you need to invoke the method on every
single Player object on the List?

If that's the case, you should normally use an Iterator:
for (Player aPlayer : playerList) {
if (aPlayer meets your requirements) {
aPlayer.updateMethod("Phillip");
}
}

Or if you know exactly which element in the list to be updated without
iterating the list, you can try:
playerList.get(X).updateName("Phillip");

Note that in your original post, the instantiation of a new Player
object is unnecessary.

If you prefer to work with an array, why do you create an array in the
first place? Or after constructing the list, change it to an array
using:
Player[] players = playerList.toArray(new Player[]);

then do whatever you'd like with the array...
 
R

Roedy Green

Player tempPlayer = new Player();
tempPlayer = (Player) playerList.get(X);
tempPlayer.updateName("Phillip");

Do you use the index for anything? If not, you might use some sort of
Collection other than ArrayList that gives you a faster way to look up
by name, e.g. a HashMap

Then you can say something like this:

Player p = playerList.get( oldname );
p.setSetName ( newName );

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

If ever need a list of all the players, HashMap will emit an array or
an Iterator for you.

If you need random access, create TWO collections on the same set of
Player objects, an ArrayList for access by index and a HashMap for
index by name.
 
C

Chris Uppal

Colin said:
Player tempPlayer = new Player();
tempPlayer = (Player) playerList.get(X);
tempPlayer.updateName("Phillip");

You have misunderstood how Java, and specifically Java collections, work. The
array list holds a collection of /references/ to objects (pointers to objects
in C++ terms). So when you do
tempPlayer = (Player) playerList.get(X)
you are fetching a reference to a Player object from the list and assigning
that reference (/NOT/ the object) to the tempPlayer variable. It may help to
think in implementation terms: that's fetching the 32-bit address[*] of the
Player object out of the list of addresses, and assigning it to the 32-bit
variable tempPlayer. The object itself is not copied.

I hope the above made sense; if it did then you'll be able to see why creating
a new Player on the previous line is pointless and, in fact, a mistake.

-- chris

([*] Actually this is an implementation detail which may vary according the JVM
you are using, it may be 64-bits rather than 32, it may not even be an
"address" as such, but the idea is the same.)
 
L

Lasse Reichstein Nielsen

Colin Hemmings said:
I have filled the ArrayList with several player objects. My player
objects have a method called 'updateName()', which changes that
players name with the name it is passed.
Currently to change the name of a player in the ArrayList I have to do
the following:
Player tempPlayer = new Player();

You don't need to create a new Player here. Just
Player templPlayer;
will do, and you can even put it on the next line:
tempPlayer = (Player) playerList.get(X);

Player tempPlayer = (Player) playerList.get(X);
tempPlayer.updateName("Phillip");

Unless you use the tempPlayer variable later, you don't need it at all
(see below). You might want it for readability though. Some people
prefer to only do one thing in each statement, and not both getting
the element out of the list and calling a method on it.
This code works fine, but I was wondering if there is a way of
manipulating the object just using its reference, without having to
retrieve the entire object.

This sounds like you are misunderstanding something fundamental.

In Java, objects exist in the heap memory. They are never passed
around as an "entire object". Only their references are passed
around. What you get out of "playerList.get" *is* a reference
to the object.
For instance, something similar to the following:
playerList[X].updateName("Phillip"); Similar to the way you access
elements in a standard array?

How about:

((Player)playerList.get(X)).updateName("Phillip");


If you use Java 5 generics, you can even avoid the cast.

List<Player> playerList = new ArrayList<Player>();
....
playerList.get(X).updateName("Phillip");

Or is there a better way of accessing elements than what I am doing
in the first example?

Using the "get" method is usually the best way of getting a specific
element out of an ArrayList (if you know the index, obviously). If you
want to get them all out, you can use an iterator, which has the
advantage of also working efficiently on a LinkedList.

/L
 
C

Colin Hemmings

Thanks for everyones help, I seemed to get the problem sorted. I did
understand that the ArrayList simply held a reference to the object, I
just didnt know how to use the get access to the referenced object's
methods. The following worked:
((Player)playerList.get(X)).updateName("Phillip");
I tried something similar just just didnt cast it to type player before.

once again thankyou all
 
D

Dimitri Maziuk

Colin Hemmings sez:
Player tempPlayer = new Player();
tempPlayer = (Player) playerList.get(X);
tempPlayer.updateName("Phillip");

This code works fine, but I was wondering if there is a way of
manipulating the object just using its reference, without having to
retrieve the entire object.

You misunderstand and I believe this to be the result of Java's
fscked-up terminology wrt. "pass by value" and "reference": in
Player x;
x is a pointer and the pointer is what's stored in the list
and returned by .get(). So you are not retrieving the entire
object, you're getting a pointer.
tempPlayer = new Player();
is bad since
tempPlayer = (Player) playerList.get(X)
re-points the pointer and simply discards the object you've
just created with "new". All it does is sit on the heap
waiting to be garbage-collected.

....For instance, something similar to the
following:
playerList[X].updateName("Phillip");
Similar to the way you access elements in a standard array?

Since get() returns a pointer, you can substitute:
((Player) playerList.get(X)).updateName("Phillip");
Or is there a better way of accessing elements than what I am doing in
the first example?

Define "better". For ArrayList there's no difference between
for( Iterator i = list.iterator(); i.hasNext(); )
((cast) i.next()).method();
and
for( int i = 0; i < list.size(); i++ )
((cast) list.get(i)).method();

For linked list, the second loop is list.size() times slower
(i.e. iterator loop is better in case ArrayList gets replaced
by a LinkedList later on).

Java 1.5's genericized list and foreach loop provide a nice
shorthand for the iterator loop above ("best": iterator loop
and less typing).

Dima
 
R

Roedy Green

You misunderstand and I believe this to be the result of Java's
fscked-up terminology wrt. "pass by value" and "reference": in
Player x;

"fucked up" is not the right term. Perhaps "fragile". You have to
get it exactly right to understand it. The problem is, people come
from other languages and expect Java to do things in the familiar way,
and it does not. It is hard to explain Java parameter passing in ways
that can't possibly be twisted or misinterpreted.

I don't know how anyone ever figures it out without thinking in terms
of what happens in machine language.

I give my shot at it in http://mindprod.com/jgloss/passbyvalue.html
and http://mindprod.com/jgloss/passbyreference.html
 

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