Random thoughts about randomness in Scala

Alonso Del Arte
3 min readNov 14, 2024

--

Photo by Jonathan Petersson on Unsplash

When you need a pseudorandom number in a Java project, what do you use? Many Java programmers would probably just use Math.random(). Which is just fine if what you need is precisely a pseudorandom floating point number that’s at least 0.0 and but less than 1.0.

Most of the time, though, at least in my experience, what’s needed is a pseudorandom integer. Like, for example, a pseudorandom integer from 1 to 10. We might write

int number = (int) (10 * Math.random()) + 1;

This is error-prone. I’m speaking from personal experience. Like, one time, I misplaced the parentheses and the “random” number was always 1. Or it was always 10. Or something like that. I almost needed to use the debugger, which I’d rather not.

There has to be a better way to get pseudorandom integers without having to worry about screwing up the formula. Just being able to specify you want a number that’s at least 0 but less than a given positive number would be a huge improvement.

There is such a way. Looking at the source of Math.random(), I learned that the first call to that function in a given session of the Java Virtual Machine causes a new instance of java.util.Random to come into being.

Each call to Math.random() causes a call to the Random instance’s nextDouble() function. But Random has a lot of other functions besides nextDouble(), like nextInt(), which can give any 32-bit signed integer or it can give a bounded nonnegative number, such as, for example, an integer between 0 and 127 (this example would use a bound parameter of 128).

And Java 17 added an overload of nextInt() that also takes an origin parameter. With that function, you can specify, for example, that you want a pseudorandom number between −72 and 72, instead of having to ask for a number between 0 and 144 and then having to subtract 72.

Whatever’s available in a Java project on a given system should also be available to a Scala project on that same system. So we should be able to import java.util.Random, instantiate it and use it.

But Scala provides a yet better way, with the class scala.util.Random and its companion object. The companion object gives the convenience of not having to instantiate a new Random object each time you need a pseudorandom number.

You still need to put in an import forscala.util.Random, if you don’t have a wildcard import for scala.util._ (which I don’t recommend just as I don’t recommend importing java.util.*).

Scala also provides the alphanumeric() function, which is very nice when you need a String of pseudorandom alphanumeric ASCII characters, even though it can be a little cumbersome to use. For example,

val alphaNum = Random.alphanumeric
new String(alphaNum.take(8).toArray)

might give you “W1vcC1Hx”. Still, it’s better than writing your own function from scratch.

If you’ve got a better way to use alphanumeric() to get a String of a specific length, please post it in the comments.

--

--

Alonso Del Arte
Alonso Del Arte

Written by Alonso Del Arte

is a Java and Scala developer from Detroit, Michigan. AWS Cloud Practitioner Foundational certified

No responses yet