will
will

Reputation: 35

Fail to randomize java string array

I want to randomize or shuffle the order of the string array using the code below

public static void main(String[] args) {
        String str[]= {"Vxds", "Cvda", "Xcgi", "Atdr", "Mbeds", "0bda"};
        String strTmp[]=str;
        
        ArrayList<Integer> list = new ArrayList<Integer>();
        for (int i=0; i<str.length; i++) {
            list.add(new Integer(i));
        }
        
        Collections.shuffle(list);
        
        for (int i=0; i<str.length; i++) {
            strTmp[i]=str[list.get(i)];
            System.out.println(strTmp[i]);
        }
    }

The reason I do it like this instead of print it out directly is because I want to make it into a function later on. That's why I passed it to strTmp[] as that is what I want the function to return. But, the code just didn't function as I expected. It prints out several same value. How can I do it the right way? Thanks for the answer...

Upvotes: 1

Views: 94

Answers (4)

Anonymous
Anonymous

Reputation: 86333

When you do String strTmp[]=str;, both str and strTmp are references to the same array. So when putting elements in, you are overwriting old elements including those have not yet been moved.

You may just do

    String str[]= {"Vxds", "Cvda", "Xcgi", "Atdr", "Mbeds", "0bda"};
    Collections.shuffle(Arrays.asList(str));

This works because Arrays.asList() does not create a new list, it merely provides a list view on the array. Any changes to the list change the array. Including shuffling it. Edit: This works for an array of strings and an array of any other reference type. As WJS points out, this will not work for an array of primitives (e.g., int[]) since Arrays.asList(arrayOfPrimitives) will create a list view of a newly created array of one elemeent, the primitive array.

If you require a new array with the shuffled strings and the old array unmodified, the solution is:

    List<String> list = new ArrayList<>(Arrays.asList(str));
    Collections.shuffle(list);
    String[] newStr = list.toArray(new String[0]);
    
    System.out.println("Original array:     " + Arrays.toString(str));
    System.out.println("New shuffled array: " + Arrays.toString(newStr));

Edit: Output from one example run:

Original array:     [Vxds, Cvda, Xcgi, Atdr, Mbeds, 0bda]
New shuffled array: [0bda, Cvda, Mbeds, Vxds, Xcgi, Atdr]

As you can see, the original array is unmodified.

Edit: Since Java 11 it’s nicer to create the new array using Collection.toArray(IntFunction<String[]>):

    String[] newStr = list.toArray(String[]::new);

See both code snippets run live in IdeOne.

Upvotes: 2

user4910279
user4910279

Reputation:

If you don't want to change the array str. Try this.

String str[] = {"Vxds", "Cvda", "Xcgi", "Atdr", "Mbeds", "0bda"};
String strTmp[] = str.clone();
Collections.shuffle(Arrays.asList(strTmp));
System.out.println(Arrays.toString(strTmp));

output

[Xcgi, Cvda, Atdr, Mbeds, 0bda, Vxds]

Upvotes: 2

Murat Karag&#246;z
Murat Karag&#246;z

Reputation: 37604

You almost had it, but you are referencing the same array twice and swap the contents of it. Change this line

 String strTmp[] = str;

to

 String strTmp[] = new String[str.length];

Upvotes: 4

Leo S
Leo S

Reputation: 339

I understand that you want to randomized your array in every execute. Here is the code for this.

import java.util.*;    

 public static void main(String[] args) {
        String str[]= {"Vxds", "Cvda", "Xcgi", "Atdr", "Mbeds", "0bda"};    
        List<String> list =Arrays.asList(str);
        Collections.shuffle(list);
        System.out.println(list);
     }

Upvotes: 1

Related Questions