1. Псевдослучайные числа
Иногда программист сталкивается с простыми, казалось бы, задачами: «отобрать случайный фильм для вечернего просмотра из определенного списка», «выбрать победителя лотереи», «перемешать список песен при тряске смартфона», «выбрать случайное число для шифрования сообщения», и каждый раз у него возникает очень закономерный вопрос: а как получить это самое случайное число?
Вообще-то, если вам нужно получить «настоящее случайное число», сделать это довольно-таки трудно. Вплоть до того, что в компьютер встраивают специальные математические сопроцессоры, которые умеют генерировать такие числа, с выполнением всех требований к «истинной случайности».
Поэтому программисты придумали свое решение — псевдослучайные числа. Псевдослучайные числа — это некая последовательность, числа в которой на первый взгляд кажутся случайными, но специалист при детальном анализе сможет найти в них определенные закономерности. Для шифрования секретных документов такие числа не подойдут, а для имитации бросания кубика в игре — вполне.
Есть много алгоритмов генерации последовательности псевдослучайных чисел и почти все из них генерируют следующее случайное число на основе предыдущего и еще каких-то вспомогательных чисел.
Например, данная программа выведет на экран 1000 неповторяющихся чисел:
public class Main
{
public static int a = 41;
public static int c = 11119;
public static int m = 11113;
public static int seed = 1;
public static int getNextRandom()
{
seed = (a * seed + c) % m;
return seed;
}
public static void main(String[] args)
{
for (int i = 0; i < 1000; i++)
{
System.out.println(getNextRandom());
}
}
}
Кстати, мы говорим не о псевдослучайных числах, а именно о последовательности таких чисел. Т.к. глядя на одно число невозможно понять, случайное оно или нет.
Случайное число ведь можно получить разными способами:
public static int getRandomNumber()
{
return 4; // это точно случайное число (выкинул его с помощью кубиков)
}
2. Метод Math.random()
В Java у класса Math есть специальный метод, который возвращает случайное число. И, как вы возможно догадываетесь, метод называется random. Общий вид его вызова выглядит так:
Math.random()
Этот метод не принимает никаких параметров, но возвращает результат — псевдослучайное вещественное число в диапазоне от 0 до 1. Единица при этом в диапазон не входит.
Пример:
| Код | Вывод на экран |
|---|---|
|
|
Но что, если вам этот метод не очень подходит, а вы хотите, допустим, написать программу, которая имитирует выбрасывание кубика с шестью гранями. Как получить случайные целые числа в диапазоне 1..6, а не вещественные в диапазоне 0..1?
Это на самом деле довольно просто.
Сначала нужно превратить диапазон [0,1) в [0, 6). Для этого нужно просто умножить результат функции random() на 6. Ну а чтобы получить целые числа, нужно это все округлить:
| Код | Вывод на экран |
|---|---|
|
|
Функция getRandomDiceNumber() возвращает случайное целое число из диапазона 0..5 включительно. Только это будут не числа из набора 1,2,3,4,5,6, а числа из набора 0,1,2,3,4,5.
Если требуются именно числа из набора 1,2,3,4,5,6, нужно просто ко всем случайным числам добавлять единицу:
| Код | Вывод на экран |
|---|---|
|
|
Вот теперь идеально!
3. Класс Random
В Java есть специальный класс Random, который инкапсулирует в себе последовательность псевдослучайных чисел. Можно создать несколько объектов класса Random, и каждый из этих объектов будет генерировать свою последовательность псевдослучайных чисел.
Это очень интересный класс, и у него есть много интересных методов. Начнем с самых простых:
Метод double nextDouble()
Этот метод возвращает случайное вещественное число в диапазоне 0.0 – 1.0. Очень похоже на метод Math.random(). И ничего удивительного, ведь метод Math.random() просто вызывает метод nextDouble() у объекта типа Random.
Метод float nextFloat()
Метод очень похож на метод nextDouble(), только возвращаемое случайное число типа float. Оно также лежит в диапазоне 0.0 – 1.0. И, как всегда, в Java диапазон не включает число 1.0.
Random r = new Random();
float f = r.nextFloat();
Метод int nextInt(int max)
Этот метод возвращает случайное целое число в диапазоне [0, max). 0 входит в диапазон, max — не входит.
Т.е. если вы хотите получить случайное число из набора 1, 2, 3, 4, 5, 6, вам нужно будет прибавить к полученному случайному числу единицу:
Random r = new Random();
int x = r.nextInt(6) + 1;
Метод int nextInt()
Этот метод аналогичен предыдущему, но не принимает никаких параметров. Тогда в каком же диапазоне он выдает числа? От -2 миллиарда до +2 миллиарда.
Ну или если точнее, от -2147483648 до +2147483647.
Метод long nextLong()
Этот метод аналогичен методу nextInt(), только возвращаемое значение будет из всего возможного диапазона значений типа long.
Метод boolean nextBoolean()
Этот метод возвращает случайное значение типа boolean: false или true. Очень удобно, если нужно получить длинную последовательность случайных логических значений.
Метод void nextBytes(byte[] data)
Этот метод ничего не возвращает (тип void). Вместо этого он заполняет переданный в него массив случайными значениями. Очень удобно, если нужен большой буфер, заполненный случайными данными.
Метод double nextGaussian()
Этот метод возвращает случайное вещественное число в диапазоне 0.0 — 1.0. Вот только числа в этом диапазоне распределены не равномерно, а подчиняются нормальному распределению.
Числа ближе к середине диапазона (0.5) будут выпадать чаще, чем значение по краям диапазона.

Пик значений в нашем случае придется на 0.5
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ