Sådan genereres tilfældige tal i Java

⚡ Smart opsummering

Tilfældige tal i Java kommer fra fire relaterede standardbiblioteksmuligheder, Random-klassen, Math.random, ThreadLocalRandom og SecureRandom, der hver dækker en forskellig blanding af hastighed, trådsikkerhed og kryptografisk styrke til virkelige applikationer.

  • 🎲 Tilfældig klasse: java.util.Random eksponerer nextInt, nextLong, nextDouble, og nextBoolean for almindelige primitive typer.
  • 🧮 Matematik.tilfældig: Math.random returnerer en double mellem 0.0 inklusive og 1.0 eksklusiv ved hjælp af en delt Random-instans.
  • 🎯 Brugerdefinerede intervaller: Send en grænse til nextInt eller skaler Math.random for at generere værdier inden for et hvilket som helst minimum og maksimum.
  • 🧵 Trådsikkerhed: ThreadLocalRandom i java.util.concurrent giver hver tråd sin egen generator og overgår en delt Random under content.
  • 🔐 Sikkerhed: SecureRandom i java.security producerer kryptografisk stærke værdier for adgangskoder, tokens og sessionsnøgler.
  • ???? Reproducerbarhed: At seede en tilfældig værdi med en fast long gør test og simuleringer deterministiske på tværs af kørsler.

Sådan genereres tilfældige tal i Java

Tilfældige tal dukker op overalt i Java, fra enhedstestdata og terningkastspil til sessionsbrikker og blandede sæt kort. Denne vejledning forklarer, hvordan man genererer tilfældige tal i Java brug af alle muligheder i standardbiblioteket og hvordan man vælger den rigtige til jobbet.

Generer tilfældigt tal i Java

Java Standardbiblioteket tilbyder fire almindelige måder at generere et tilfældigt tal på:

  • java.util.Random er den generelle klasse. Den producerer boolske, int-, long-, float- og double-værdier gennem metoder som f.eks. nextInt, nextLongog nextDouble.
  • Math.random er en statisk hjælper, der returnerer en double mellem 0.0 (inklusive) og 1.0 (eksklusiv) ved hjælp af en delt Random internt.
  • ThreadLocalRandom in java.util.concurrent giver hver tråd sin egen generator, så flere tråde ikke konkurrerer om en enkelt instans.
  • SecureRandom in java.security producerer kryptografisk stærke pseudo-tilfældige tal til adgangskoder, sessionsidentifikatorer og nøgler.

Afsnittene nedenfor viser, hvordan man genererer ti tilfældige tal med hver metode.

Eksempel: Generer tilfældigt tal vha Java Tilfældig klasse

Det første eksempel bruger java.util.Random for at producere ti heltal i området fra 0 til 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);
        }
    }
}

Output:

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

Et eksempel på Random er skabt som objGenerator. Det nextInt(int bound) Metoden returnerer en værdi mellem 0 (inklusive) og den angivne grænse (eksklusiv), så nextInt(100) giver værdier fra 0 til 99. For at gøre sekvensen reproducerbar, send et seed til konstruktøren, for eksempel new Random(42); det samme frø producerer altid den samme sekvens, hvilket er nyttigt i tests og simuleringer.

Eksempel: Brug af Java Matematik.tilfældig

For at generere ti tilfældige værdier i området 0.0 til 1.0, skal du kalde den statiske Math.random metode inde i en loopDette er den hurtigste måde at opnå en tilfældig fordobling uden at oprette et generatorobjekt:

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

Output:

0.46518450373334297
0.14859851177803485
0.5628391820492477
0.6323378498048606
0.1740198445692248
0.9140544122258946
0.9167350036262347
0.49251219841030147
0.7426056725722353
0.2039418871298877

Under kølerhjelmen, Math.random skaber en enkelt statisk Random ved første brug og opkald nextDouble på den. Den ene delte generator er fin til demoer, men bliver en flaskehals under tung multithreaded-belastning, hvilket de næste afsnit omhandler.

Generer et tilfældigt tal i et brugerdefineret område

Rigtige programmer har normalt brug for en tilfældig værdi inden for et bestemt interval, såsom et heltal mellem 1 og 6 for et terningkast eller en fordobling mellem 10.0 og 20.0 for en simulering. To mønstre dækker næsten alle tilfælde.

Tilfældigt heltal mellem min og max (inklusive):

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);
    }
}

Tilfældig fordobling mellem min og max:

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

Begge mønstre fungerer ved at tage en værdi fra generatorens native område, skalere den til bredden af ​​målområdet og forskyde den op med minimum. Hvis du er på Java 8 eller nyere, det samme resultat er tilgængeligt via den nyere ints, longsog doubles streammetoder på Random, For eksempel rnd.ints(10, 1, 7).forEach(System.out::println) for ti terningkast.

ThreadLocalRandom for multithreaded Code

En enkelt delt Random er trådsikker, men langsom under konkurrence, fordi hver tråd skal synkroniseres på det samme interne seed. ThreadLocalRandom, tilføjet i Java 7 og bor i java.util.concurrent, giver hver tråd sin egen generator, så der ikke er nogen låsekonflikt.

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);
    }
}

Brug ThreadLocalRandom.current() i arbejdstråde, parallelle strømme og enhver samtidig opgave. Bemærk at setSeed kaster UnsupportedOperationException, så såning for reproducerbarhed understøttes ikke; hvis du har brug for et fast såkorn, skal du holde dig til almindeligt Random.

SecureRandom til sikkerhedsfølsom tilfældighed Numbers

Forekomster af Random og ThreadLocalRandom er ikke kryptografisk sikre. Med få outputeksempler kan en angriber rekonstruere den interne tilstand og forudsige fremtidige værdier. For adgangskoder, sessionstokens, saltværdier og kryptografiske nøgler skal du bruge java.security.SecureRandom i stedet. Den trækker kimmateriale fra operativsystemets entropipulje og producerer værdier, der modstår forudsigelser.

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 er langsommere end Random fordi den bruger stærkere algoritmer og rigere seed-materiale. Reserver den til sikkerhedsarbejde og brug de hurtigere generatorer til spil, simuleringer og testdata.

Ofte Stillede Spørgsmål

Opret en java.util.Random-instans og kald nextInt, nextLong og nextDoubleeller nextBoolean. For en hurtig one-liner, brug Math.random, som returnerer en double mellem 0.0 og 1.0. Begge tilgange leveres med standardbiblioteket.

Kald random.nextInt(max – min + 1) + min for heltal, eller min + (max – min) * Math.random() for doblinger. Formlerne skalerer generatorens område til dit målvindue og forskyder med minimumsværdien.

Random er en komplet klasse med metoder til mange primitive typer og understøtter seeding. Math.random er en statisk hjælper, der returnerer en double mellem 0.0 og 1.0. Internt kalder Math.random en enkelt delt Random-instans.

Ja, men samtidige kald konkurrerer på det samme interne seed, hvilket forsinker kraftigt threaded kode. Brug ThreadLocalRandom.current() fra java.util.concurrent til at give hver tråd sin egen generator og fjerne denne confidence.

Send en fast long til Random-konstruktøren, for eksempel new Random(42), eller kald setSeed(42). Generatoren vil producere den samme sekvens ved hver kørsel, hvilket er essentielt for gentagelige tests og simuleringer.

Brug SecureRandom, når værdien skal modstå forudsigelse, såsom adgangskoder, sessionstokens, saltværdier, engangskoder og kryptografiske nøgler. Plain Random er hurtig, men forudsigelig, så den er usikker til sikkerhedsarbejde.

Maskinlæringsframeworks bruger pseudo-tilfældige generatorer til at initialisere vægte, blande træningsdata og opdele valideringssæt. Ved at rette et seed-system bliver eksperimenter reproducerbare, så teams kan sammenligne modelkørsler og fejlfinde resultater pålideligt.

Ja. GitHub Copilot scaffolder Random-, ThreadLocalRandom- og SecureRandom-snippets, matchende formler til skalering af rækkevidde og JUnit tests. RevSe hvert forslag for at bekræfte, at den valgte klasse passer til brugsscenariet, især for sikkerhedsfølsom kode.

Opsummer dette indlæg med: