JavaRush /Курси /Java Syntax Zero /Випадкові числа в Java

Випадкові числа в Java

Java Syntax Zero
Рівень 9 , Лекція 2
Відкрита

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()

Клас Math у Java має спеціальний метод, який повертає випадкове число. І як ви вже, можливо, здогадуєтеся, цей метод має назву random. Його виклик має такий загальний вигляд:

Math.random()

Метод не отримує жодного параметра, але повертає результат — псевдовипадкове дійсне число в діапазоні від 0 до 1. Одиниця до діапазону не входить.

Приклад:

Код Виведення на екран
public class Main
{
   public static void main(String[] args)
   {
     for (int i = 0; i < 10; i++)
     {
       System.out.println(Math.random());
     }
   }
} 
0.9703753971734451
0.09979423801773157
0.994048474709053
0.2852203204171295
0.13551248551226025
0.3128547131272822
0.5342480554101412
0.6817369932044817
0.1840767788961758
0.06969563435451254

А що робити, якщо вам цей метод не дуже підходить, а ви хочете, припустімо, написати програму, яка імітує кидання кубика з шістьма гранями? Як отримати випадкові цілі числа в діапазоні 1…6, а не дійсні в діапазоні 0…1?

Насправді це досить просто.

Спочатку треба перетворити діапазон [0,1) на [0, 6). Для цього просто слід помножити результат функції random() на 6. Ну а щоб отримати цілі числа, потрібно це все округлити:

Код Виведення на екран
public class Main
{
   public static int getRandomDiceNumber()
   {
      return (int) (Math.random() * 6);
   }

   public static void main(String[] args)
   {
      for (int i = 0; i < 10; i++)
      {
         int x = getRandomDiceNumber();
         System.out.println(x);
      }
   }
}
5
2
3
3
2
4
1
1
5
0

Функція getRandomDiceNumber() повертає випадкове ціле число з діапазону 0…5 включно. Тільки це будуть числа не з набору 1,2,3,4,5,6, а з набору 0,1,2,3,4,5.

Якщо потрібні числа саме з набору 1,2,3,4,5,6, слід просто до всіх випадкових чисел додавати одиницю:

Код Виведення на екран
public class Main
{
   public static int getRandomDiceNumber()
   {
      return (int) (Math.random() * 6) + 1;
   }

   public static void main(String[] args)
   {
     for (int i = 0; i < 10; i++)
     {
       int x = getRandomDiceNumber();
       System.out.println(x);
     }
   }
}
3
2
1
3
6
5
6
1
6
6

Отепер ідеально!



3. Клас Random

У Java є спеціальний клас Random, який інкапсулює послідовність псевдовипадкових чисел. Можна створити кілька об'єктів класу Random, і кожен із цих об'єктів генеруватиме свою послідовність псевдовипадкових чисел.

Це дуже цікавий клас, і він має багато цікавих методів. Почнімо з найпростіших:

Метод double nextDouble()

Цей метод повертає випадкове дійсне число в діапазоні 0.01.0. Дуже схоже на метод Math.random(). І нічого дивного, адже метод Math.random() просто викликає метод nextDouble() для об'єкта типу Random.

Метод float nextFloat()

Метод дуже схожий на метод nextDouble(), тільки повертає він випадкове число типу float. Воно також лежить в діапазоні 0.01.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.01.0. От тільки числа в цьому діапазоні розподілені не рівномірно, а підпорядковані нормальному розподілу.

Числа, ближчі до середини діапазону (0.5), випадатимуть частіше, ніж значення по краях діапазону.

Клас Random

Пік значень у нашому випадку припаде на 0.5.


Коментарі (20)
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ
⭐ Ihor Voloshyn ⭐ Рівень 15
26 січня 2026

String[] arr = {CERTAIN, DEFINITELY, MOST_LIKELY, OUTLOOK_GOOD, ASK_AGAIN_LATER, TRY_AGAIN, NO, VERY_DOUBTFUL};
Random random = new Random();
int randomNumber = random.nextInt(8);
return (randomNumber >= 0 && randomNumber <= 7) ? arr[randomNumber] : null;
laura-svg Рівень 14
29 грудня 2024
ATTENTION PLEASE, хто в IDEA. Там є ДРУГИЙ клас MagicBall!!!!!!!!!!!!!!!!!!
4 грудня 2024
я звісно не експерт, але якщо в реалізації рандому я вказав максимальне число 7, то яким чином там має бути щось що не ходить в діапазон щоб отримати null?
Гаркін Рівень 14
10 березня 2024
Як, як?! Завдання Magic 8 ball - package ua.javarush.task.pro.task08.task0805; Використовую int ans = r.nextInt(answers.length); Тобто результат роботи (згідно теорії!) це

Цей метод повертає випадкове ціле число в діапазоні [0, max). 
0 входить до діапазону, max — не входить.

Тобто [0, 8). Чому при перевірці видає «рекомендацію» «Переконайтесь, що метод повертає null, якщо випадкове число виходить за межі діапазону від 0 до 7 (включно).» Як воно може виходити, якщо максимум заданий answers.length , а мінімум це 0 ?! Ps. Переглянув відповідь. То капець. Використовувати else if та ще вводити перевірку } else { return null; } ?! А відповідь не повинна включати ось ці «0 -> » чи «6 ->» ? та *тут лайка* !!! Ось такий код прийняло:

public static String getPrediction() {
    //напишіть тут ваш код
    String[] answers = {CERTAIN, DEFINITELY, MOST_LIKELY, OUTLOOK_GOOD,
            ASK_AGAIN_LATER, TRY_AGAIN, NO, VERY_DOUBTFUL};
    Random r = new Random();
    int ans = r.nextInt(answers.length);
    if (ans>=0 && ans<answers.length) {
        return answers[ans];
    } else {
        return null;
    }
}
ivan Рівень 10
31 липня 2024
Робив по схожому умова була іншою не приймало, й зробив у лоба else if.. хоча цей варіант мені до вподоби більше
les_yeux_blancs Рівень 50
22 квітня 2023
Цікаво, що воно не приймає моє рішення, хоча воно повністю відповідає умові:

    public static String getPrediction() {
        var num = new Random().nextInt(8);
        String[] options = {CERTAIN, DEFINITELY, MOST_LIKELY, OUTLOOK_GOOD, ASK_AGAIN_LATER, TRY_AGAIN, NO, VERY_DOUBTFUL};
        return num > 7 ? null : options[num];
    }
P.S. ну і я не зрозумів, в чому прикол вимоги з null, коли цієї ситуації не може бути, так як ми отримуємо інт в діапазоні 0-7
Vitalii Рівень 11
15 серпня 2023
ви не перевіряєте num < 0 на приклад. воно там іноді пише причину.
les_yeux_blancs Рівень 50
10 жовтня 2023
nextInt(int) не може повернути негативне число: результат не може бути менше 0
Mykhailo Рівень 16
28 березня 2023
вирішив з першого разу з допомогою switch, набагато простіше if-else
Василь Рівень 4
29 липня 2023
я за допомогою текстового масиву заповненого константами
Сергій Рівень 14
3 лютого 2023
Цікава задача, правда вирішив з 5-го разу, тому що не дочитав умову до кінця )
Alexoria Рівень 12
13 січня 2023
1 раз прописати switch - нє нє 100 разів прописати if-else - даааааа
Сергій Рівень 13
28 травня 2024
Я теж використав switch. Але на скільки памятаю по пройденому - то про switch ще не розповідали. Тому і використали ті "можливості" які знає наразі людина яка вчить з нуля.
Beisik Рівень 25
18 жовтня 2022
зразу й не поняв що можна було зробити останню задачу через массив ))).Зробив чисто через if else 😂 Ну за то з першого разу пройшов
Sanya Рівень 11 Expert
11 квітня 2023
Але як не крути а якийсь if else потрібен для null...
22 червня 2022
Чому IDEA пише попередження: Condition 'random == 7' is always 'true'?
les_yeux_blancs Рівень 50
22 квітня 2023
Нічого дивного, якщо уважно вивчити код зверху вниз До цієї первірки ти вже перевірив усі інші варіанти, а тому число в діапазоні 0-7, яке не являє собою 0, 1, 2, 3, 4, 5 або 6 явно являє собою 7