Как да генерирате произволно число в Java

⚡ Умно обобщение

Случайни числа в Java идват от четири свързани опции на стандартната библиотека, класа Random, Math.random, ThreadLocalRandom и SecureRandom, всяка от които покрива различна комбинация от скорост, безопасност на нишките и криптографска сила за реални приложения.

  • 🎲 Случаен клас: java.util.Random предоставя nextInt, nextLong, nextDoubleи nextBoolean за често срещани примитивни типове.
  • 🧮 Math.random: Math.random връща double между 0.0 включително и 1.0 без тях, използвайки споделен екземпляр на Random.
  • 🎯 Персонализирани диапазони: Предайте граница на nextInt или мащабирайте Math.random, за да генерирате стойности в рамките на произволен минимум и максимум.
  • 🧵 Безопасност на нишките: ThreadLocalRandom в java.util.concurrent дава на всяка нишка собствен генератор и превъзхожда споделения Random при конкуренция.
  • 🔐 Сигурност: SecureRandom в java.security генерира криптографски силни стойности за пароли, токени и ключове за сесия.
  • ???? Възпроизводимост: Засяването на Random с фиксирана дължина прави тестовете и симулациите детерминистични в различните изпълнения.

Как да генерирате произволно число в Java

Случайни числа се появяват навсякъде в Java, от данни от модулни тестове и игри с хвърляне на зарове до жетони за сесия и разбъркани тестета карти. Този урок обяснява как да се генерират случайни числа в Java използване на всяка опция в стандартната библиотека и как да се избере правилната за задачата.

Генериране на случайно число в Java

- Java Стандартната библиотека предлага четири често срещани начина за генериране на случайно число:

  • java.util.Random е клас с общо предназначение. Той генерира булеви, int, long, float и double стойности чрез методи като nextInt, nextLong, и nextDouble.
  • Math.random е статичен помощник, който връща double между 0.0 (включително) и 1.0 (изключително), използвайки споделен метод. Random вътрешно.
  • ThreadLocalRandom in java.util.concurrent дава на всяка нишка собствен генератор, така че множество нишки не се конкурират в един екземпляр.
  • SecureRandom in java.security генерира криптографски силни псевдослучайни числа за пароли, идентификатори на сесии и ключове.

Разделите по-долу показват как да се генерират десет случайни числа с всеки подход.

Пример: Генериране на произволно число с помощта на Java Случаен клас

Първият пример използва java.util.Random за да се получат десет цели числа в диапазона от 0 до 99 включително:

import java.util.Random;

public class RandomNumbers {
    public static void main(String[] args) {
        Random objGenerator = new Random();
        for (int iCount = 0; iCount < 10; iCount++) {
            int randomNumber = objGenerator.nextInt(100);
            System.out.println("Random No : " + randomNumber);
        }
    }
}

Изход:

Random No : 17
Random No : 57
Random No : 73
Random No : 48
Random No : 68
Random No : 86
Random No : 34
Random No : 97
Random No : 73
Random No : 18

Пример за Random е създаден като objGenerator, Най- nextInt(int bound) методът връща стойност между 0 (включително) и предоставената граница (изключващо), така че nextInt(100) дава стойности от 0 до 99. За да направите последователността възпроизводима, подайте начален елемент (seed) на конструктора, например new Random(42); едно и също семе винаги произвежда една и съща последователност, което е полезно при тестове и симулации.

Пример: Използване Java Math.random

За да генерирате десет случайни стойности в диапазона от 0.0 до 1.0, извикайте static Math.random метод вътре в контурТова е най-бързият начин да получите произволно двойно число, без да създавате обект генератор:

public class DemoRandom {
    public static void main(String[] args) {
        for (int xCount = 0; xCount < 10; xCount++) {
            System.out.println(Math.random());
        }
    }
}

Изход:

0.46518450373334297
0.14859851177803485
0.5628391820492477
0.6323378498048606
0.1740198445692248
0.9140544122258946
0.9167350036262347
0.49251219841030147
0.7426056725722353
0.2039418871298877

под капака, Math.random създава единична статика Random при първото използване и повикванията nextDouble върху него. Този един споделен генератор е подходящ за демонстрации, но се превръща в пречка при голямо многонишково натоварване, което ще бъде разгледано в следващите раздели.

Генериране на случайно число в персонализиран диапазон

Реалните програми обикновено се нуждаят от случайна стойност в определен диапазон, като например цяло число между 1 и 6 за хвърляне на зар или двойно число между 10.0 и 20.0 за симулация. Два модела покриват почти всеки случай.

Случайно цяло число между min и max (включително):

import java.util.Random;

public class RangeDemo {
    public static void main(String[] args) {
        Random rnd = new Random();
        int min = 1;
        int max = 6;
        // nextInt(max - min + 1) returns 0..(max-min), then shift by min
        int dice = rnd.nextInt(max - min + 1) + min;
        System.out.println("Dice roll : " + dice);
    }
}

Случайно двойно между минимум и максимум:

double min = 10.0;
double max = 20.0;
double value = min + (max - min) * Math.random();
System.out.println("Value : " + value);

И двата модела работят, като вземат стойност от естествения диапазон на генератора, мащабират я до ширината на целевия диапазон и я изместват нагоре с минимума. Ако сте на Java 8 или по-нова версия, същият резултат е наличен и чрез по-новата ints, longs, и doubles методи за поточно предаване на Random, Например rnd.ints(10, 1, 7).forEach(System.out::println) за десет хвърляния на зарчета.

ThreadLocalRandom за многонишкови Code

Един споделен Random е безопасен за нишки, но бавен при конфликт, защото всяка нишка трябва да се синхронизира върху едно и също вътрешно начално число (seed). ThreadLocalRandom, добавено в Java 7 и живее в java.util.concurrent, дава на всяка нишка собствен генератор, така че няма конфликт за заключване.

import java.util.concurrent.ThreadLocalRandom;

public class ThreadLocalDemo {
    public static void main(String[] args) {
        // random int in [1, 100]
        int i = ThreadLocalRandom.current().nextInt(1, 101);

        // random long in [1000, 5000]
        long l = ThreadLocalRandom.current().nextLong(1000L, 5001L);

        // random double in [0.0, 1.0)
        double d = ThreadLocalRandom.current().nextDouble();

        System.out.println(i + " " + l + " " + d);
    }
}

употреба ThreadLocalRandom.current() вътре в работни нишки, паралелни потоци и всяка едновременна задача. Обърнете внимание, че setSeed хвърля UnsupportedOperationException, така че засяването за възпроизводимост не се поддържа; ако имате нужда от фиксирано засяване, придържайте се към обикновен Random.

SecureRandom за чувствителна към сигурността случайна функция Numbers

Случаи на Random намлява ThreadLocalRandom не са криптографски защитени. Като се имат предвид няколко изходни извадки, атакуващият може да реконструира вътрешното състояние и да предскаже бъдещи стойности. За пароли, токени за сесия, стойности на сол и криптографски ключове използвайте java.security.SecureRandom Вместо това. Той черпи начален материал от ентропийния пула на операционната система и произвежда стойности, които се противопоставят на предвиждането.

import java.security.SecureRandom;

public class SecureDemo {
    public static void main(String[] args) {
        SecureRandom secure = new SecureRandom();

        byte[] token = new byte[16];
        secure.nextBytes(token);          // 128-bit random token

        int otp = secure.nextInt(1_000_000); // 6-digit one-time code

        System.out.println("OTP : " + String.format("%06d", otp));
    }
}

SecureRandom е по-бавно от Random защото използва по-силни алгоритми и по-богат начален материал. Запазете го за работа по сигурността и използвайте по-бързите генератори за игри, симулации и тестови данни.

Въпроси и Отговори

Създайте екземпляр на java.util.Random и извикайте nextInt, nextLong, nextDoubleили nextBoolean. За бърз едноредов отговор използвайте Math.random, който връща double между 0.0 и 1.0. И двата подхода се доставят със стандартната библиотека.

Извикайте random.nextInt(max – min + 1) + min за цели числа или min + (max – min) * Math.random() за двойни числа. Формулите мащабират диапазона на генератора до целевия прозорец и го изместват с минималната стойност.

Random е пълноценен клас с методи за много примитивни типове и поддържа начално ниво (seeding). Math.random е статичен помощник, който връща double между 0.0 и 1.0. Вътрешно, Math.random извиква един споделен екземпляр на Random.

Да, но едновременните извиквания се конкурират за едно и също вътрешно начало, което забавя силно нишковидния код. Използвайте ThreadLocalRandom.current() от java.util.concurrent, за да дадете на всяка нишка собствен генератор и да премахнете това съревнование.

Предайте фиксирана стойност long на конструктора Random, например new Random(42), или извикайте setSeed(42). Генераторът ще генерира една и съща последователност при всяко изпълнение, което е от съществено значение за повтарящи се тестове и симулации.

Използвайте SecureRandom винаги, когато стойността трябва да устои на предвиждане, например пароли, токени за сесия, стойности на сол, еднократни кодове и криптографски ключове. Plain Random е бърз, но предвидим, така че е опасен за работа, свързана със сигурността.

Рамките за машинно обучение използват псевдослучайни генератори за инициализиране на тегла, разместване на данни за обучение и разделяне на валидационни набори. Фиксирането на начално число прави експериментите възпроизводими, така че екипите да могат да сравняват изпълненията на модели и надеждно да отстраняват грешки в резултатите.

Да. GitHub Copilot скафолдира Random, ThreadLocalRandom и SecureRandom фрагменти, съответстващи на формули за мащабиране на диапазони и JUnit тестове. RevПрегледайте всяко предложение, за да потвърдите, че избраният клас отговаря на случая на употреба, особено за код, чувствителен към сигурността.

Обобщете тази публикация с: