One thing I miss most of all is the ease of messing with arrays. In PHP, there are no distinctions between types, so any data can be in any array. In Java of course, things are very different. If you want an array of numbers, it needs to be an int array. If it’s an array of a particular object, it needs to be an array of objects of that type. It is very restrictive if you’re not used to a strongly typed language.
This week, I had to shuffle an array. In other words, take it’s ordered version and mess it up randomly. I don’t have a computer science background, so I can’t make a good way to mess up an array. (And considering I’d have to have overloads and stupid Java things, it’s even worse.) I did find some solutions though.
Solution 1 – Hard – (deprecated)
Random rgen = new Random(); // Random number generator int[] cards = new int[52]; //--- Initialize the array to the ints 0-51 for (int i=0; i < cards.length; i++) { cards[i] = i; } //--- Shuffle by exchanging each element randomly for (int i=0; i < cards.length; i++) { int randomPosition = rgen.nextInt(cards.length); int temp = cards[i]; cards[i] = cards[randomPosition]; cards[randomPosition] = temp; }
This example is from Java: shuffling. This example is fine but it takes some good knowledge of arrays and the way to make things random to figure out how exactly to do this. You certainly wouldn’t want to write all of that when you want an array randomized.
Note: Ken Arnold in the comments states that this code will result in a random but non-equally distributed result. See his comment for details and my own comments on this problem.
Solution 2 – Easy
// Create a list List list = new ArrayList(); // Add elements to list // Shuffle the elements in the list Collections.shuffle(list); // Create an array String[] array = new String[]{"a", "b", "c"}; // Shuffle the elements in the array Collections.shuffle(Arrays.asList(array));
These two examples, above, come from Java Developers Almanac Example. The example shows how simple it is to shuffle a primitive array. By using the Arrays class, you can force the primitive-array to be a list. And for actual lists, you don’t need to do anything but call the shuffle method from collections and pass it the reference to the list.
I wish Java would make it easier for people to find things like this though. Google led me to these answers. Not a single site was leading to any sun/java/etc page. All firendly forums or personal or project/book sites.
Update
I have written more on shuffling arrays. In that post, I describe the noted problem above with the original randomization method.
Thanks so much Ryan, this helped a ton.
Thanks a lot for this!!
Collections.shuffle(Arrays.asList(array)); doesnt work for int arrays, probably because it isnt Object. Be aware of it!
“>” should be replaced with “<" in the first code sample.
Thanks, pal. Collections.shuffle helped a lot…
True, it does not work, but if you’re trying to shuffle an array of int, instead declaring:
int[] array = new array[]{1,2,3}
Use an integer object:
Integer[] array = new Integer[]{1,2,3}
Works with Double, Float, etc..
There is no hand-holding tutorial for this because it can easily be achieved with a loop and an RNG. I don’t know why there is the .shuffle() method for List but not for Array, though. Java is known for its extensive library, there should be tool for every tiny thing in this universe, in my opinion.
Nice laptop by the way. Really jealous of you.
It’s funny. Java has a huge and extensive library but there are many glaring omissions. A couple I can point out immediately: sha1/crypto strings instead of byte arrays and painfully obvious array methods, like this one. But on the other hand, look at PHP. It has just about every function under the sun but such a poor naming convention, it’s almost criminal.
the hard method is wrong this part:
for (int i=0; i > cards.length; i++)
and the correct form is :
for (int i=0; i is wrong, it should be <
just click the java:shuffling link and you will see
This has helped me so much Ryan, I could kiss you!
Nice post, but I have to say that your “hard” code makes a common error. Because that is the fast loop to use, it’s probably a good idea to correct the post, especially since this article is the top google hit for “java shuffle array”. It’s an easy error to make, I made it in my first card game, and it was explained to me thusly:
When you choose a value to swap with, you must choose from the unshuffled parts of the array, not including already shuffled values:
int randomPosition = i + rgen.nextInt(cards.length – i);
It’s funny, it doesn’t seem like this should matter. It’s random in either case, right?
I can’t describe exactly how it goes wrong but you can prove it’s wrong anyway.
Let’s say you are shuffling 4 values. There are 4! possible orders. 4! = 4 * 3 * 2 * 1 = 24.
If instead you pick *any* element to swap with (as in the original code) including already-shuffled values, there are 4^4 possibilities. 4^4 = 256
Note that 256 is not a multiple of 24.
So there cannot be an even distribution of the actual 4! possibilities within 4^4 outputs. So the 4^4 algorithm (as in your original code) cannot be producing all 4! possibilities with equal probability.