Math.random() в Java возвращает псевдослучайное число типа double в диапазоне от 0.0 (включительно) до 1.0 (исключительно). Чтобы сгенерировать целое число в заданном диапазоне (от min до max), используйте формулу: (int) (((max - min) + 1) * Math.random()) + min. Обе границы входят в диапазон: при min = 1 и max = 6 получится честный бросок кубика, то есть числа от 1 до 6 включительно.
Хотя эта формула может показаться сложной, она очень проста в применении. Давайте разберем ее на практических примерах, начиная с основ и заканчивая использованием для реальных задач.Метод java.lang.Math.random() возвращает псевдослучайное число типа double в диапазоне от 0.0 до 1.0. Метод живет в классе java.lang.Math рядом с остальной математикой, поэтому импортировать ничего не нужно, а его описание есть в документации Oracle. Следовательно, случайное число, сгенерированное с помощью встроенного метода Java, всегда находится в диапазоне от 0 до 1.
Кратко
- Math.random() возвращает double от 0.0 включительно до 1.0 исключительно, то есть единицу не выдает никогда.
- Метод статический и лежит в классе java.lang.Math, поэтому импорт не нужен.
- Целое число от 0 до n-1 получают так: (int) (Math.random() * n), а произвольный диапазон через формулу с min и max.
- Приведение к int отбрасывает дробную часть, а не округляет, поэтому в формуле и появляется + 1: без него верхняя граница выпадать не будет.
- Числа псевдослучайные: их считает алгоритм, а не физический источник случайности. Для паролей, токенов и всего, что связано с безопасностью, этот метод не подходит.
- Под капотом метод один раз создает общий генератор и дальше пользуется только им, зато он синхронизирован и безопасен при вызове из разных потоков.
Что такое метод Math.random() в Java?
0.0 ≤ random < 1.0
Обратите внимание, что случайное число больше или равно 0.0 и меньше 1.0. Как использовать Math.random() в Java?
Использовать метод Math.random() довольно просто даже для новичков.Пример 1
Давайте рассмотрим базовый пример использования метода Math.random() в Java для ясного понимания.public class RandomTest {
public static void main(String[] args) {
double random1 = Math.random();
double random2 = Math.random();
System.out.println("Первое случайное число: " + random1);
System.out.println("Второе случайное число: " + random2);
}
}Вывод
Первое случайное число: 0.5486939400685561
Второе случайное число: 0.23550115674999972
Использование метода random() в заданном диапазоне
Вызов метода Math.random() кажется довольно очевидным. Однако наша потребность в случайных числах не всегда ограничивается диапазоном от 0 до 1. Для реальных задач мы можем работать и в других указанных диапазонах. Давайте рассмотрим пример использования метода Math.random() для заданного диапазона, скажем, от 1 до 6, как на игральном кубике (про другие способы получить число в диапазоне у нас есть отдельная статья).Пример 2
public class RandomNumberInRange {
public static int getRandom(int min, int max) {
int range = (max - min) + 1;
int random = (int) (range * Math.random()) + min;
return random;
}
public static void main(String[] args) {
// Давайте сыграем в Ludo с 4 игроками
int dieRoll = getRandom(1, 6);
System.out.println("Ход красных: " + dieRoll);
dieRoll = getRandom(1, 6);
System.out.println("Ход синих: " + dieRoll);
dieRoll = getRandom(1, 6);
System.out.println("Ход зеленых: " + dieRoll);
dieRoll = getRandom(1, 6);
System.out.println("Ход желтых: " + dieRoll);
}
}Вывод
Ход красных: 3
Ход синих: 2
Ход зеленых: 6
Ход желтых: 4
Объяснение
Чтобы получить случайное число в пределах диапазона, вам нужно вычислить диапазон, вычитая min из max. Затем диапазон умножают на Math.random(), результат приводят к int и только после этого прибавляют min. Порядок здесь важен. Если прибавить min до приведения, то при отрицательном min нижняя граница выпадать не будет: приведение к int отбрасывает дробную часть в сторону нуля, а не вниз. В остальном все просто: после приведения вы получаете случайное число в указанном диапазоне. Соберем типовые задачи в одну шпаргалку:| Задача | Код | Пояснение |
|---|---|---|
| Дробное число от 0 до 1 | Math.random() | единица не выпадет никогда |
| Целое от 0 до n-1 | (int) (Math.random() * n) | привычный диапазон индексов массива |
| Целое от min до max включительно | (int) (((max - min) + 1) * Math.random()) + min | та самая формула из начала статьи |
| Бросок кубика | (int) (Math.random() * 6) + 1 | частный случай формулы при min = 1 и max = 6 |
| Случайный элемент массива | array[(int) (Math.random() * array.length)] | длина массива и есть верхняя граница |
| Случайное «да» или «нет» | Math.random() < 0.5 | примерно поровну в обе стороны |
Когда Math.random() мало
Метод умеет ровно одно: выдавать дробное число от нуля до единицы. Для задач посложнее в стандартной библиотеке есть три специальных инструмента, и все они родственники: ThreadLocalRandom и SecureRandom наследуются от java.util.Random.- java.util.Random. Тот самый класс, экземпляр которого Math.random() создает внутри себя. У него есть методы под конкретные типы: nextInt(6) сразу дает целое от 0 до 5 без умножений и приведений, а с Java 17 работает и вариант с двумя границами, nextInt(1, 7). Еще этому классу можно передать зерно в конструктор и получать одну и ту же последовательность при каждом запуске, что незаменимо в тестах.
- ThreadLocalRandom. Из пакета java.util.concurrent, доступен с Java 7. Документация Math.random() честно предупреждает: метод синхронизирован, и если много потоков просят числа часто, они начинают ждать друг друга. У ThreadLocalRandom свой генератор на каждый поток, очереди не возникает: ThreadLocalRandom.current().nextInt(1, 7).
- SecureRandom. Из пакета java.security. Единственный из трех, который годится для паролей, токенов, кодов подтверждения и всего, что защищает. Обычный генератор предсказуем: зная его состояние, можно вычислить следующие числа. SecureRandom берет случайность у операционной системы.