Generere tilfældige numre i Java

1. Oversigt

I denne vejledning undersøger vi forskellige måder at generere tilfældige tal på Java.

2. Brug af Java API

Java API giver os flere måder at nå vores mål på. Lad os se nogle af dem.

2.1. java.lang.Math

Det tilfældig metode til Matematik klasse vender tilbage a dobbelt værdi i et interval fra 0,0 (inklusive) til 1,0 (eksklusiv). Lad os se, hvordan vi bruger det til at få et tilfældigt tal i et givet interval defineret af min og maks:

int randomWithMathRandom = (int) ((Math. tilfældig () * (max - min)) + min);

2.2. java.util. tilfældighed

Før Java 1.7 var den mest populære måde at generere tilfældige tal på næsteInt. Der var to måder at bruge denne metode på, med og uden parametre. Intetparameteropkaldet returnerer noget af int værdier med omtrent lige sandsynlighed. Så det er meget sandsynligt, at vi får negative tal:

Tilfældig tilfældig = ny tilfældig (); int randomWithNextInt = random.nextInt ();

Hvis vi bruger netxInt påkaldelse med bundet parameter får vi tal inden for et interval:

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

Dette giver os et tal mellem 0 (inklusive) og parameter (eksklusiv). Så den bundne parameter skal være større end 0. Ellers får vi en java.lang.IllegalArgumentException.

Java 8 introducerede det nye ints metoder, der returnerer a java.util.stream.IntStream. Lad os se, hvordan vi bruger dem.

Det ints metode uden parametre returnerer en ubegrænset strøm af int værdier:

IntStream unlimitedIntStream = random.ints ();

Vi kan også overføre en enkelt parameter for at begrænse strømstørrelsen:

IntStream limitedIntStream = random.ints (streamSize);

Og selvfølgelig kan vi indstille maksimum og minimum for det genererede interval:

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

2.3. java.util.concurrent.ThreadLocalRandom

Java 1.7-udgivelse bragte os en ny og mere effektiv måde at generere tilfældige tal via ThreadLocalRandom klasse. Denne har tre vigtige forskelle fra Tilfældig klasse:

  • Vi behøver ikke eksplicit at starte en ny forekomst af ThreadLocalRandom. Dette hjælper os med at undgå fejl ved at skabe masser af ubrugelige forekomster og spilde tid til affaldssamler
  • Vi kan ikke sætte frøet til ThreadLocalRandom, hvilket kan føre til et reelt problem. Hvis vi har brug for at indstille frøet, bør vi undgå denne måde at generere tilfældige tal på
  • Tilfældig klasse fungerer ikke godt i miljøer med flere tråde

Lad os nu se, hvordan det fungerer:

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

Med Java 8 eller nyere har vi nye muligheder. For det første har vi to variationer til næsteInt metode:

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

For det andet og vigtigere kan vi bruge ints metode:

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

2.4. java.util.SplittableRandom

Java 8 har også bragt os en rigtig hurtig generator - SplittableRandom klasse.

Som vi kan se i JavaDoc, er dette en generator til brug i parallelle beregninger. Det er vigtigt at vide, at forekomsterne ikke er trådsikre. Så vi skal være forsigtige, når vi bruger denne klasse.

Vi har tilgængelige næsteInt og ints metoder. Med næsteInt vi kan indstille top- og bundområdet direkte ved hjælp af de to parametre påkaldelse:

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

Denne måde at bruge kontrol på, at maks parameter er større end min. Ellers får vi en IllegalArgumentException. Det kontrollerer dog ikke, om vi arbejder med positive eller negative tal. Så alle parametrene kan være negative. Vi har også tilgængelige en- og nul-parameteropkald. De fungerer på samme måde som vi har beskrevet tidligere.

Vi har tilgængelige ints metoder også. Det betyder, at vi let kan få en strøm af int værdier. For at afklare kan vi vælge at have en begrænset eller ubegrænset stream. For en begrænset stream kan vi indstille toppen og bunden for nummergenereringsområdet:

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

2.5. java.security.SecureRandom

Hvis vi har sikkerhedsfølsomme applikationer, bør vi overveje at bruge SecureRandom. Dette er en kryptografisk stærk generator. Standardkonstruktioner bruger ikke kryptografisk tilfældige frø. Så vi skal enten:

  • Indstil frøet - følgelig vil frøet være uforudsigeligt
  • Indstil java.util.secureRandomSeed systemegenskab til rigtigt

Denne klasse arver fra java.util. tilfældighed. Så vi har tilgængelige alle de metoder, vi så ovenfor. For eksempel, hvis vi har brug for at få noget af int værdier, så ringer vi næsteInt uden parametre:

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

På den anden side, hvis vi har brug for at indstille rækkevidden, kan vi kalde det med bundet parameter:

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

Vi skal huske, at denne måde at bruge den på kaster IllegalArgumentException hvis parameteren ikke er større end nul.

3. Brug af tredjeparts-API'er

Som vi har set, giver Java os mange klasser og metoder til at generere tilfældige tal. Der er dog også tredjeparts-API'er til dette formål.

Vi skal se på nogle af dem.

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

Der er mange generatorer i det fælles matematikbibliotek fra Apache Commons-projektet. Den nemmeste og sandsynligvis den mest nyttige er RandomDataGenerator. Det bruger Nå19937c algoritme til tilfældig generation. Vi kan dog levere vores algoritmeimplementering.

Lad os se, hvordan du bruger det. For det første skal vi tilføje afhængighed:

 org.apache.commons commons-math3 3.6.1 

Den seneste version af commons-math3 kan findes på Maven Central.

Så kan vi begynde at arbejde med det:

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

3.2. it.unimi.dsi.util.XoRoShiRo128PlusRandom

Bestemt er dette en af ​​de hurtigste implementeringer af tilfældige talgeneratorer. Det er udviklet på informationsvidenskabsafdelingen ved Milanos universitet.

Biblioteket er også tilgængeligt på Maven Central repositories. Så lad os tilføje afhængighed:

 it.unimi.dsi dsiutils 2.6.0 

Denne generator arver fra java.util. tilfældighed. Men hvis vi ser på JavaDoc, indser vi, at der kun er en måde at bruge den på - gennem næsteInt metode. Frem for alt er denne metode kun tilgængelig med påkald af nul og en parameter. Enhver af de andre påkaldelser bruger direkte java.util. tilfældighed metoder.

For eksempel, hvis vi ønsker at få et tilfældigt tal inden for et interval, ville vi skrive:

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

4. Konklusion

Der er flere måder at implementere tilfældigt talgenerering på. Der er dog ingen bedste måde. Derfor bør vi vælge den, der bedst passer til vores behov.

Det fulde eksempel kan findes på GitHub.


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