Pregunta

Following is a method that takes an ArrayList of Card objects, deck, as an argument, sets up a second ArrayList, shuffled, capable of holding Card objects, and then randomly picks Cards out of deck one by one, adding them to the second ArrayList. Once the deck is empty, the deck variable is assigned a reference to the newly-filled ArrayList, which is shuffled. For some reason though, when I send this method a non-empty ArrayList argument, it completely empties out the deck. Why is this?

public static void shuffle(ArrayList<Card> deck)
{
    Random randy = new Random();
    ArrayList<Card> shuffled = new ArrayList<Card>();

    while (!deck.isEmpty())
    {
        int c = randy.nextInt(deck.size());
        shuffled.add(deck.remove(c));
    }

    deck = shuffled;
}

Any insight would be appreciated.

¿Fue útil?

Solución 2

This is an example of how call by value is implemented in java . When you do the below example , your original deck is being altered

 shuffled.add(deck.remove(c));
 // Changes the value of the underlying object of deck reference, hence
 // both the original deck and the deck variable in the function are altered

The below statement only changes the reference of the variable in the function. Your original deck object still is an emptied out list

deck = shuffled;
// The deck variable in the function  is now  pointing to shuffled within
// the function. This deck variable is lost after your function call ends.

Otros consejos

deck is a local identifier which is assigned the heap location of the ArrayList which is passed in. When shuffled is declared it is assigned a different heap location. Assigning deck to shuffled does not change the original ArrayList as it is declared in the heap.

Use Collections.shuffle and save yourself some trouble.

As described in another answer, you have emptied the original arraylist, but haven't put anything back into it as you have changed the local reference only. The following code adds the shuffled items back into the original deck arraylist.

public static void shuffle(ArrayList<Card> deck)
{
    Random randy = new Random();
    ArrayList<Card> shuffled = new ArrayList<Card>();

    while (!deck.isEmpty())
    {
        int c = randy.nextInt(deck.size());
        shuffled.add(deck.remove(c));
    }

    // this line will copy the shuffled items back into the deck array
    deck.addAll(shuffled);

}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top