Genererer tilfeldige tall i Java

1. Oversikt

I denne opplæringen vil vi utforske forskjellige måter å generere tilfeldige tall på Java.

2. Bruke Java API

Java API gir oss flere måter å oppnå formålet med. La oss se noen av dem.

2.1. java.lang.Math

De tilfeldig metoden for Matte klasse vil returnere a dobbelt verdi i området fra 0,0 (inkludert) til 1,0 (eksklusivt). La oss se hvordan vi bruker det til å få et tilfeldig tall i et gitt område definert av min og maks:

int randomWithMathRandom = (int) ((Math.random () * (max - min)) + min);

2.2. java.util.Random

Før Java 1.7 var den mest populære måten å generere tilfeldige tall på nesteInt. Det var to måter å bruke denne metoden på, med og uten parametere. No-parameter påkallingen returnerer noe av int verdier med tilnærmet lik sannsynlighet. Så det er veldig sannsynlig at vi får negative tall:

Tilfeldig tilfeldig = ny Tilfeldig (); int randomWithNextInt = random.nextInt ();

Hvis vi bruker netxInt påkallelse med bundet parameter, får vi tall innenfor et område:

int randomWintNextIntWithinARange = random.nextInt (maks - min) + min;

Dette vil gi oss et tall mellom 0 (inkludert) og parameter (eksklusiv). Så, den bundne parameteren må være større enn 0. Ellers får vi en java.lang.IllegalArgumentException.

Java 8 introduserte det nye ints metoder som returnerer a java.util.stream.IntStream. La oss se hvordan du bruker dem.

De ints metode uten parametere returnerer en ubegrenset strøm av int verdier:

IntStream unlimitedIntStream = random.ints ();

Vi kan også sende inn en enkelt parameter for å begrense strømstørrelsen:

IntStream limitedIntStream = random.ints (streamSize);

Og selvfølgelig kan vi stille inn maksimum og minimum for det genererte området:

IntStream limitedIntStreamWithinARange = random.ints (streamSize, min, max);

2.3. java.util.concurrent.ThreadLocalRandom

Java 1.7-utgivelsen ga oss en ny og mer effektiv måte å generere tilfeldige tall via ThreadLocalRandom klasse. Denne har tre viktige forskjeller fra Tilfeldig klasse:

  • Vi trenger ikke å eksplisitt starte en ny forekomst av ThreadLocalRandom. Dette hjelper oss med å unngå feil ved å skape mange ubrukelige forekomster og kaste bort tid til søppel
  • Vi kan ikke sette frøet til ThreadLocalRandom, som kan føre til et reelt problem. Hvis vi trenger å sette frøet, bør vi unngå denne måten å generere tilfeldige tall på
  • Tilfeldig klasse klarer seg ikke godt i miljøer med flere tråder

La oss nå se hvordan det fungerer:

int randomWithThreadLocalRandomInARange = ThreadLocalRandom.current (). nextInt (min, max);

Med Java 8 eller nyere har vi nye muligheter. For det første har vi to varianter for nesteInt metode:

int randomWithThreadLocalRandom = ThreadLocalRandom.current (). nextInt (); int randomWithThreadLocalRandomFromZero = ThreadLocalRandom.current (). nextInt (max);

For det andre, og enda viktigere, kan vi bruke ints metode:

IntStream streamWithThreadLocalRandom = ThreadLocalRandom.current (). Ints ();

2.4. java.util.SplittableRandom

Java 8 har også gitt oss en veldig rask generator - the SplittableRandom klasse.

Som vi kan se i JavaDoc, er dette en generator for bruk i parallelle beregninger. Det er viktig å vite at forekomsten ikke er trådsikker. Så vi må være forsiktige når vi bruker denne klassen.

Vi har tilgjengelig nesteInt og ints metoder. Med nesteInt Vi kan angi topp- og bunnområdet direkte ved å bruke de to parametrene:

SplittableRandom splittableRandom = ny SplittableRandom (); int randomWithSplittableRandom = splittableRandom.nextInt (min, max);

Denne måten å bruke sjekker på at maks parameteren er større enn min. Ellers får vi en IllegalArgumentException. Imidlertid sjekker den ikke om vi jobber med positive eller negative tall. Så noen av parametrene kan være negative. Vi har også tilgjengelige en- og nullparameteranrop. De fungerer på samme måte som vi har beskrevet tidligere.

Vi har tilgjengelig ints metoder også. Dette betyr at vi enkelt kan få en strøm av int verdier. For å avklare kan vi velge å ha en begrenset eller ubegrenset strøm. For en begrenset strøm kan vi angi topp og bunn for nummergenereringsområdet:

IntStream limitedIntStreamWithinARangeWithSplittableRandom = splittableRandom.ints (streamSize, min, max);

2.5. java.security.SecureRandom

Hvis vi har sikkerhetssensitive applikasjoner, bør vi vurdere å bruke SecureRandom. Dette er en kryptografisk sterk generator. Standardkonstruerte forekomster bruker ikke kryptografisk tilfeldige frø. Så vi burde enten:

  • Sett frøet - følgelig vil frøet være uforutsigbart
  • Sett java.util.secureRandomSeed systemegenskap til ekte

Denne klassen arver fra java.util.Random. Så vi har tilgjengelig alle metodene vi så ovenfor. For eksempel hvis vi trenger å få noe av int verdier, så ringer vi nesteInt uten parametere:

SecureRandom secureRandom = ny SecureRandom (); int randomWithSecureRandom = secureRandom.nextInt ();

På den annen side, hvis vi trenger å stille inn området, kan vi kalle det med bundet parameter:

int randomWithSecureRandomWithinARange = secureRandom.nextInt (maks - min) + min;

Vi må huske at denne måten å bruke den på, kaster IllegalArgumentException hvis parameteren ikke er større enn null.

3. Bruke tredjeparts APIer

Som vi har sett, gir Java oss mange klasser og metoder for å generere tilfeldige tall. Imidlertid er det også tredjeparts APIer for dette formålet.

Vi skal ta en titt på noen av dem.

3.1. org.apache.commons.math3.random.RandomDataGenerator

Det er mange generatorer i commons matematikkbibliotek fra Apache Commons-prosjektet. Den enkleste, og sannsynligvis den mest nyttige, er RandomDataGenerator. Den bruker Vel19937c algoritme for tilfeldig generasjon. Imidlertid kan vi tilby algoritmeimplementering.

La oss se hvordan du bruker den. For det første må vi legge til avhengighet:

 org.apache.commons commons-math3 3.6.1 

Den siste versjonen av commons-math3 kan du finne på Maven Central.

Så kan vi begynne å jobbe med det:

RandomDataGenerator randomDataGenerator = ny RandomDataGenerator (); int randomWithRandomDataGenerator = randomDataGenerator.nextInt (min, maks);

3.2. it.unimi.dsi.util.XoRoShiRo128PlusRandom

Dette er absolutt en av de raskeste implementeringene av tilfeldige tallgeneratorer. Den er utviklet ved Institutt for informasjonsvitenskap ved universitetet i Milano.

Biblioteket er også tilgjengelig på Maven Central repositories. Så la oss legge til avhengighet:

 it.unimi.dsi dsiutils 2.6.0 

Denne generatoren arver fra java.util.Random. Men hvis vi tar en titt på JavaDoc, innser vi at det bare er en måte å bruke den på - gjennom nesteInt metode. Fremfor alt er denne metoden bare tilgjengelig med null- og en-parameter-påkallingen. Enhver av de andre påkallelsene vil bruke direkte java.util.Random metoder.

For eksempel, hvis vi ønsker å få et tilfeldig tall innenfor et område, vil vi skrive:

XoRoShiRo128PlusRandom xoroRandom = ny XoRoShiRo128PlusRandom (); int randomWithXoRoShiRo128PlusRandom = xoroRandom.nextInt (maks - min) + min;

4. Konklusjon

Det er flere måter å implementere tilfeldig nummergenerering på. Det er imidlertid ingen beste måte. Derfor bør vi velge den som passer best til våre behov.

Det fulle eksemplet finner du på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found