SophomoreNumberN
SophomoreNumberN

Reputation: 82

How do I get shuffle() from Collections to not modify every array in a list?

I'm trying to get Collections.shuffle() to shuffle only one array is a list of 3 arrays made using Collections.nCopies() (ex: I only want it to shuffle the first array, but it ends up shuffling every array in the list) Here's what I've done so far. I have been trying to look through Google for the same problem but the only examples provided are Strings or Integers, no Arrays.

x is 3 and slotType.getSlotitems() is for the array ["Apple","Cherry","Banana"]

List<ArrayList<String>> q = Collections.nCopies(x,slotType.getSlotitems());

        for (ArrayList<String> v : q) {
            java.util.Collections.shuffle(v);
            System.out.println(v);
            System.out.println(q);
        }

The result that shows up is:

[Cherry, Banana, Apple]
[[Cherry, Banana, Apple], [Cherry, Banana, Apple], [Cherry, Banana, Apple]]
[Cherry, Banana, Apple]
[[Cherry, Banana, Apple], [Cherry, Banana, Apple], [Cherry, Banana, Apple]]
[Cherry, Apple, Banana]
[[Cherry, Apple, Banana], [Cherry, Apple, Banana], [Cherry, Apple, Banana]]

Upvotes: 2

Views: 485

Answers (1)

Eran
Eran

Reputation: 393781

nCopies doesn't create copies of the element you pass to it, so q contains a List where the same ArrayList<String> instance is repeated x times. When you shuffle one of them, you shuffle all of them (since there is actually only one of them).

To create a List of x distinct copies, you can use Streams:

List<ArrayList<String>> q = 
    IntStream.range(0,x)
             .mapToObj(i -> new ArrayList<String>(slotType.getSlotitems()))
             .collect(Collectors.toList());

Now shuffle would only affect one of the ArrayLists.

Another option:

  List<ArrayList<String>> q =
      Collections.nCopies(x,slotType.getSlotitems())
                 .stream()
                 .map(ArrayList::new)
                 .collect(Collectors.toList());

Here I took your original List<ArrayList<String>> (where all the elements are the same instance) and created a new List<ArrayList<String>> where each element is a copy of the original element.

Upvotes: 1

Related Questions