Kuinka luoda satunnaislukua sisään Java
⚡ Älykäs yhteenveto
Satunnaisia lukuja Java tulevat neljästä toisiinsa liittyvästä standardikirjastovaihtoehdosta: Random-luokasta, Math.randomista, ThreadLocalRandomista ja SecureRandomista, joista kukin kattaa erilaisen nopeuden, säikeiden turvallisuuden ja kryptografisen vahvuuden yhdistelmän todellisissa sovelluksissa.

Satunnaisia numeroita näkyy kaikkialla Java, yksikkötestausdatasta ja nopanheittopeleistä istuntomerkkeihin ja sekoitettuihin pakkoihin. Tässä tutoriaalissa selitetään, miten satunnaislukuja luodaan Java standardikirjaston kaikkien vaihtoehtojen käyttäminen ja oikean vaihtoehdon valitseminen työhön.
Luo satunnaisluku sisään Java
Java standardikirjasto tarjoaa neljä yleistä tapaa satunnaisluvun luomiseen:
java.util.Randomon yleiskäyttöinen luokka. Se tuottaa totuusarvoja, kokonaislukuja, long-lukuja, float-lukuja ja double-lukuja esimerkiksi seuraavilla metodeilla:nextInt,nextLongjanextDouble.Math.randomon staattinen apufunktio, joka palauttaa tupla-arvon välillä 0.0 (mukaan lukien) ja 1.0 (poissulkevasti) käyttäen jaettuaRandomsisäisesti.ThreadLocalRandominjava.util.concurrentantaa jokaiselle säikeelle oman generaattorin, joten useat säikeet eivät kilpaile yhdestä instanssista.SecureRandominjava.securitytuottaa kryptografisesti vahvoja pseudo-satunnaislukuja salasanoille, istuntotunnisteille ja avaimille.
Alla olevat osiot näyttävät, kuinka kullakin lähestymistavalla luodaan kymmenen satunnaislukua.
Esimerkki: Luo satunnaisluku käyttämällä Java Satunnainen luokka
Ensimmäisessä esimerkissä käytetään java.util.Random tuottaaksesi kymmenen kokonaislukua väliltä 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); } } }
lähtö:
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
Esimerkki Random luodaan nimellä objGenerator. nextInt(int bound) metodi palauttaa arvon nollan (mukaan lukien) ja annetun rajan (poissulkeva) väliltä, joten nextInt(100) antaa arvoja väliltä 0 - 99. Jotta sekvenssi olisi toistettavissa, anna siemen konstruktorille, esimerkiksi new Random(42)sama siemen tuottaa aina saman sekvenssin, mikä on hyödyllistä testeissä ja simulaatioissa.
Esimerkki: käyttäminen Java Math.random
Kymmenen satunnaisarvon luomiseksi väliltä 0.0–1.0, kutsu staattista Math.random menetelmä sisällä silmukkaTämä on nopein tapa saada satunnainen tupla luomatta generaattoriobjektia:
public class DemoRandom { public static void main(String[] args) { for (int xCount = 0; xCount < 10; xCount++) { System.out.println(Math.random()); } } }
lähtö:
0.46518450373334297 0.14859851177803485 0.5628391820492477 0.6323378498048606 0.1740198445692248 0.9140544122258946 0.9167350036262347 0.49251219841030147 0.7426056725722353 0.2039418871298877
Konepellin alle, Math.random luo yhden staattisen elementin Random ensimmäisellä käyttökerralla ja puheluissa nextDouble Tuo yksi jaettu generaattori sopii demoille, mutta siitä tulee pullonkaula raskaan monisäikeisen kuormituksen alla, mitä käsitellään seuraavissa osioissa.
Satunnaisluvun luominen mukautetulla alueella
Todellisissa ohjelmissa tarvitaan yleensä satunnaisluku tietyllä alueella, kuten kokonaisluku väliltä 1 ja 6 nopanheittoa varten tai tuplaus väliltä 10.0 ja 20.0 simulaatiota varten. Kaksi mallia kattavat lähes kaikki tapaukset.
Satunnainen kokonaisluku min:n ja max:n välillä (mukaan lukien):
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); } }
Satunnainen tuplaus min- ja max-arvojen välillä:
double min = 10.0; double max = 20.0; double value = min + (max - min) * Math.random(); System.out.println("Value : " + value);
Molemmat mallit toimivat ottamalla arvon generaattorin natiivista alueesta, skaalaamalla sen kohdealueen leveyteen ja siirtämällä sitä ylöspäin minimin verran. Jos olet päällä Java 8 tai uudemmassa versiossa sama tulos on saatavilla uudemman version kautta. ints, longsja doubles stream-metodit päällä Random, esimerkiksi rnd.ints(10, 1, 7).forEach(System.out::println) kymmenelle nopanheitolle.
ThreadLocalRandom monisäikeisille Code
Yksi jaettu Random on säikeiden kannalta turvallinen, mutta hidas kilpailun aikana, koska jokaisen säikeen on synkronoitava samaan sisäiseen siemeneen. ThreadLocalRandom, lisätty sisään Java 7 ja asuu java.util.concurrent, antaa jokaiselle säikeelle oman generaattorin, joten lukituskilpailua ei tapahdu.
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); } }
Käyttää ThreadLocalRandom.current() työsäikeiden, rinnakkaisten virtojen ja kaikkien samanaikaisten tehtävien sisällä. Huomaa, että setSeed heittää UnsupportedOperationException, joten toistettavuuden siementämistä ei tueta; jos tarvitset kiinteän siemenen, käytä tavallista Random.
SecureRandom turvallisuusherkille satunnaisille tiedoille Numbers
Tapaukset Random ja ThreadLocalRandom eivät ole kryptografisesti turvallisia. Muutaman tulosnäytteen perusteella hyökkääjä voi rekonstruoida sisäisen tilan ja ennustaa tulevia arvoja. Salasanojen, istuntotunnusten, suola-arvojen ja kryptografisten avainten osalta käytä java.security.SecureRandom sen sijaan. Se ammentaa siemenmateriaalia käyttöjärjestelmän entropiavarastosta ja tuottaa arvoja, joita ei voida ennustaa.
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 on hitaampaa kuin Random koska se käyttää vahvempia algoritmeja ja rikkaampaa alkumateriaalia. Varaa se tietoturvatyöhön ja käytä nopeampia generaattoreita peleihin, simulaatioihin ja testidataan.
