Skip to main content
GameDev.net gamedev.net
🔒 Locked

Array lists in java.

Started by GDKnight Jan 22, 2006 at 5:29 AM 9 replies 7.1k views
Original Post
GDKnight
GDKnight
Im trying to swap things in an array list using java and its not working at all. It is really getting on my nerves.

	public void shuffleDeck()
	{
		Random generator = new Random();
		Object [] cardArray = m_Cards.toArray();
		for(int x=0; x<generator.nextInt(1000)+10; x++)
		{
			for(int i=0; i<52; i++)
			{
				int randomIndex = generator.nextInt(52);
				swap((Card)m_Cards, (Card)m_Cards[randomIndex]);
			}
		}
	}


As you can see I was expecting it to swap the references in the array list and its not doing this. Can someone show me how to do this?
GDKnight
haegarr
haegarr
Any swapping that may occur here is hidden in the swap(...) routine, so please post it, too (but see (2) below).

But notice these things first, please. (There is some confusion between array and ArrayList, I think. What kind is m_Cards of? I'll treat it as array below.)

(1) Your outer loop means you shuffle your deck between 10 and 1010 time. The stop condition changes at each iteration. It this your desire?

(2) You can't swap the references sensefully in swap(...) but the content of the both card instances. I expect you wanted to do something like
public void shuffleDeck(){   Random generator = new Random();//   Object [] cardArray = m_Cards.toArray(); // <-- what is this good for?   for(int x=0; x<generator.nextInt(1000)+10; x++)   {      for(int i=0; i<m_Cards.length; i++) // <-- use length instead of hard-coded value      {          final int randomIndex = generator.nextInt(m_Cards.length); // <-- use length instead of hard-coded value          Card temp = (Card)m_Cards;          m_Cards = (Card)m_Cards[randomIndex];          m_Cards[randomIndex] = temp;      }   }}

instead?!

(3) What is the local variable cardArray for? In the posted implementation it is unneeded yet.
RayNbow
RayNbow
If you want to swap two elements in an array, you could do this (without error checking):

public static void swap(Object[] array, int index1, int index2) {    Object temp = array[index1];    array[index1] = array[index2];    array[index2] = temp;}


And here's a version that works with ArrayLists:

public static void swap(ArrayList array, int index1, int index2) {    Object temp = array.get(index1);    array.set(index1, array.get(index2));    array.set(index2, temp);}


GDKnight
GDKnight
Here is the hidden "swap" function I made as you can see it just swaps them.
	private void swap(Card c1, Card c2)	{		Card tmpCard = c1;		c1 = c2;		c2 = tmpCard;	}


Card temp = (Card)m_Cards;
m_Cards = (Card)m_Cards[randomIndex];
m_Cards[randomIndex] = temp

I would of done this but java gives an error.

array required, but java.util.ArrayList found
Card temp = (Card)m_Cards;
GDKnight
snk_kid
snk_kid
Quote:
Original post by GDKnight
Card temp = (Card)m_Cards;
m_Cards = (Card)m_Cards[randomIndex];
m_Cards[randomIndex] = temp

I would of done this but java gives an error.

array required, but java.util.ArrayList found
Card temp = (Card)m_Cards;


ArrayList is a class, java has no mechanism to overload operators for user-defined types such as ArrayList therefore it does not have a subcript operator, you have to use one of the named accessor methods to get the elements out of an instance of ArrayList. Also as i mentioned earlier if you want to shuffle the elements in an instance of ArrayList (or any collection that is a sub-type of (implements) List) you can use util.Collections.shuffle.

Lastly why are you not using generics (and the generic version of ArrayList)? java 1.5 has been out for quite some-time now there is not much of an excuse to not use them anymore.
OrangyTang
OrangyTang
Quote:
Original post by GDKnight
I would of done this but java gives an error.

array required, but java.util.ArrayList found
Card temp = (Card)m_Cards;

You can't use array indexing (the [] syntax) on an ArrayList, you have to use the method .get(i) instead.

Also, in your original source ArrayList.toArray() returns a new array which includes the contents of the original ArrayList - you can modify the Card objects via this, but any changes in the order of the array are independant of the ArrayList (which is why your swap doesn't appear to be working when you look at the ArrayList again).

And m_ style notation is generally avoided in Java.
RayNbow
RayNbow
Quote:
Original post by GDKnight
Here is the hidden "swap" function I made as you can see it just swaps them.
*** Source Snippet Removed ***

When you call that function like this:
Card foo = new Card();Card bar = new Card();swap(foo, bar);

The variables foo and bar are copied. That's right, pass by value.
No, not the Card objects themselves, but the addresses/pointers/whatever-you-want-to-call-it are copied.

You can change the copies of these variables inside the function, the variables outside the function remain unchanged. The only thing you can change this way are the objects the variables point to.
haegarr
haegarr
Quote:
Original post by GDKnight
Here is the hidden "swap" function I made as you can see it just swaps them.
*** Source Snippet Removed ***

I would of done this but java gives an error.

array required, but java.util.ArrayList found
Card temp = (Card)m_Cards;

That is why my post above says "some confusion between array and ArrayList" and "I'll treat it as array below".

The replies above have already handled the problem. To step from theory to practice, I update my above code snippet for ArrayList here:
public void shuffleDeck(){   Random generator = new Random();   for(int x=0; x<generator.nextInt(1000)+10; x++)   {      for(int i=0; i<m_Cards.size(); i++)      {          final int randomIndex = generator.nextInt(m_Cards.size());          Object temp = m_Cards.get(i);          m_Cards.set(i,m_Cards.get(randomIndex));          m_Cards.set(randomIndex,temp);      }   }}

If you don't use generics, then you have stored "Object" instances in the ArrayList, and you need not to cast while operating inside the ArrayList only. But if you use generics (snk_kid pointed to it), then the handled objects are known being Card instances, and you also should not need to cast.

Furthurmore the array.length is replaced by ArrayList.size(), of course. I've left all other stuff as is. But consider the tips of the replies above, please.
Zahlman
Zahlman
Quote:
Original post by RayNbow
Quote:
Original post by GDKnight
Here is the hidden "swap" function I made as you can see it just swaps them.
*** Source Snippet Removed ***

When you call that function like this:
Card foo = new Card();Card bar = new Card();swap(foo, bar);

The variables foo and bar are copied. That's right, pass by value.
No, not the Card objects themselves, but the addresses/pointers/whatever-you-want-to-call-it are copied.

You can change the copies of these variables inside the function, the variables outside the function remain unchanged. The only thing you can change this way are the objects the variables point to.


Further clarification.
Raghar
Raghar
Quote:
Original post by RayNbow

The variables foo and bar are copied. That's right, pass by value.
No, not the Card objects themselves, but the addresses/pointers/whatever-you-want-to-call-it are copied.


It's better to say: It's regcall. So both references are passed by register, and if user will not move them to nonvolatile location then they are removed from registers after not needed.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.