Случайные числа

Случайные числа – это важная часть многих программ и игр. Они придают приложениям элемент неопределённости и интереса. Однако, на самом деле, компьютеры не способны генерировать абсолютно случайные числа. Вместо этого они используют псевдослучайные числа, которые создаются с использованием некоторых алгоритмов. Как сгенерировать случайное число в Java? Обо всём по порядку.

Псевдослучайность

Псевдослучайные числа – это числа, которые создаются на основе начального значения, называемого “сид” (seed). Если вы используете один и тот же сид, то вы всегда получите одну и ту же последовательность чисел. Это может быть полезно для отладки и воспроизведения результатов, но не является истинно случайным.

Для создания статистически непредсказуемых чисел используются различные сложные формулы. У каждого такого алгоритма должен быть достаточно длинный период. Любой генератор рано или поздно начинает повторять последовательность, и чем позже это случится, тем лучше.

Но мы не будем писать такие генераторы – а зачем? Уже есть готовые реализации рандома, и в Java это встроенные библиотеки. Познакомимся с ними.

java.util.Random

В Java есть достаточно удобный класс для операций со случайными числами, и это – класс Random из пакета java.util. Попробуем поиграться с его функционалом:

Скриншот консоли IntelliJ IDEA со случайными числами и boolean

Отличный результат. И значения при перезапуске программы будут меняться – на то они и (псевдо)случайные. Хотя у класса Random есть метод генерации целого числа int до определённой верхней границы, нижнюю границу мы задать всё-таки не можем. Это можно исправить.

Давайте напишем класс, который позволит генерировать случайные целые и вещественные (дробные) числа в задаваемых диапазонах. Кстати, random.nextDouble() генерирует вещественное число весьма своеобразным образом – от 0 до 1 (единица не включена в диапазон). Перед классом разместим javadoc-комментарий – один из трёх видов комментариев в Java.

Теперь мы сможем использовать этот класс для генерации чисел в заданных рамках. Протестируем функционал класса в методе main():

Задав границы [-2; 4], мы получили 5 целых и 5 вещественных чисел в этом диапазоне. Это достаточно удобно. Такой класс можно было бы использовать в разных программах: играх, социальных сетях и даже гороскопах.

Скриншот консоли IntelliJ IDEA со случайными целыми и вещественными числами от -2 до 4

Math.random()

В Java существует класс Math, который предоставляет функционал по многим необходимым математическим вычислениям, от возведения в степень до вычисления синуса. В данный момент этот класс нам интересен тем, что он также умеет генерировать случайные числа. Правда, делает он это так же, как и random.nextDouble(), так что для удобного использования тоже придётся написать самостоятельно парочку методов.

Напишем сперва простую программу, использующую этот самый Math.random():

Скриншот консоли IntelliJ IDEA со случайными целыми и вещественными числами
Скриншот консоли IntelliJ IDEA со случайными целыми и вещественными числами

При каждом перезапуске программы числа генерироваться будут разные. Но метод Math.random(), опять же, какой-то сырой. Ну где может пригодиться генерирование исключительно от 0 до 1? Давайте переделаем класс Randomizer под использование метода Math.random().

Заметьте, какова структура получившейся программы: для внесения изменений способа генерации случайных чисел нам пришлось поменять только два метода класса Randomizer generateInt() и generateLong(). Никакие внешние классы и методы (в том числе метод main(), откуда мы тестируем класс Randomizer) и не подозревают о внесённых изменениях. Вот это вежливое обращение с кодом. Итого, в метод main() не нужно вносить абсолютно никаких изменений. Это пахнет инкапсуляцией из ООП.

Запустим программу, чтобы убедиться, что числа исправно генерируются в заданном диапазоне:

Скриншот консоли IntelliJ IDEA со случайными целыми и вещественными числами от 100 до 200

Да, всё работает ровно так, как ожидается, а это – главная цель программистов. В диапазоне [100; 200] генерируются как целые, так и вещественные числа, причём разница во внутренней реализации класса Randomizer не видна стороннему пользователю – для него ничего не изменилось.

Теперь, имея понимание работы генераторов случайных чисел, вы можете успешно использовать их в проектах, добавляя случайность и разнообразие в программу.

Добавить комментарий