32 import java.util.stream.LongStream; |
32 import java.util.stream.LongStream; |
33 import java.util.stream.Stream; |
33 import java.util.stream.Stream; |
34 |
34 |
35 /** |
35 /** |
36 * The {@link RandomGenerator} interface is designed to provide a common protocol for objects that |
36 * The {@link RandomGenerator} interface is designed to provide a common protocol for objects that |
37 * generate random or (more typically) pseudorandom sequences of numbers (or Boolean values). Such a |
37 * generate random or (more typically) pseudorandom sequences of numbers (or Boolean values). |
38 * sequence may be obtained by either repeatedly invoking a method that returns a single |
38 * Such a sequence may be obtained by either repeatedly invoking a method that returns a single |
39 * (pseudo)randomly chosen value, or by invoking a method that returns a stream of (pseudo)randomly |
39 * (pseudo)randomly chosen value, or by invoking a method that returns a stream of (pseudo)randomly |
40 * chosen values. |
40 * chosen values. |
41 * <p> |
41 * <p> |
42 * Ideally, given an implicitly or explicitly specified range of values, each value would be chosen |
42 * Ideally, given an implicitly or explicitly specified range of values, each value would be chosen |
43 * independently and uniformly from that range. In practice, one may have to settle for some |
43 * independently and uniformly from that range. In practice, one may have to settle for some |
57 * stream of 100 {@code int} values. These are not necessarily the exact same values that would |
57 * stream of 100 {@code int} values. These are not necessarily the exact same values that would |
58 * have been returned if instead {@code r.nextInt()} had been called 100 times; all that is |
58 * have been returned if instead {@code r.nextInt()} had been called 100 times; all that is |
59 * guaranteed is that each value in the stream is chosen in a similar (pseudo)random manner from the |
59 * guaranteed is that each value in the stream is chosen in a similar (pseudo)random manner from the |
60 * same range. |
60 * same range. |
61 * <p> |
61 * <p> |
62 * Every object that implements the {@link RandomGenerator} interface is assumed to contain a finite |
62 * Every object that implements the {@link RandomNumberGenerator} interface by using a |
63 * amount of state. Using such an object to generate a pseudorandomly chosen value alters its |
63 * pseudorandom algorithm is assumed to contain a finite amount of state. Using such an object to |
64 * state. The number of distinct possible states of such an object is called its |
64 * generate a pseudorandomly chosen value alters its state by computing a new state as a function |
65 * <i>period</i>. (Some implementations of the {@link RandomGenerator} interface |
65 * of the current state, without reference to any information other than the current state. |
66 * may be truly random rather than pseudorandom, for example relying on the statistical behavior of |
66 * The number of distinct possible states of such an object is called its <i>period</i>. |
67 * a physical object to derive chosen values. Such implementations do not have a fixed period.) |
67 * (Some implementations of the {@link RandomNumberGenerator} interface may be truly random |
|
68 * rather than pseudorandom, for example relying on the statistical behavior of a physical |
|
69 * object to derive chosen values. Such implementations do not have a fixed period.) |
68 * <p> |
70 * <p> |
69 * As a rule, objects that implement the {@link RandomGenerator} interface need not be thread-safe. |
71 * As a rule, objects that implement the {@link RandomGenerator} interface need not be thread-safe. |
70 * It is recommended that multithreaded applications use either {@link ThreadLocalRandom} or |
72 * It is recommended that multithreaded applications use either {@link ThreadLocalRandom} or |
71 * (preferably) pseudorandom number generators that implement the {@link SplittableGenerator} or |
73 * (preferably) pseudorandom number generators that implement the {@link SplittableGenerator} or |
72 * {@link JumpableGenerator} interface. |
74 * {@link JumpableGenerator} interface. |
73 * <p> |
75 * <p> |
74 * To implement this interface, a class only needs to provide concrete definitions for the methods |
76 * To implement this interface, a class only needs to provide concrete definitions for the methods |
75 * {@code nextLong()} and {@code period()}. Default implementations are provided for all other |
77 * {@code nextLong()} and {@code period()}. Default implementations are provided for all other |
76 * methods (but it may be desirable to override some of them, especially {@code nextInt()} if the |
78 * methods (but it may be desirable to override some of them, especially {@code nextInt()} if the |
77 * underlying algorithm is {@code int}-based). Moerover, it may be preferable instead to implement |
79 * underlying algorithm is {@code int}-based). Moreover, it may be preferable instead to implement |
78 * another interface such as {@link JumpableGenerator} or {@link LeapableGenerator}, or to extend an |
80 * a more specialized interface such as {@link JumpableGenerator} or {@link LeapableGenerator}, |
79 * abstract class such as {@link AbstractSplittableGenerator} or {@link |
81 * or to extend an abstract implementation-support class such as {@link AbstractSplittableGenerator} |
80 * AbstractArbitrarilyJumpableGenerator}. |
82 * or {@link AbstractArbitrarilyJumpableGenerator}. |
81 * <p> |
83 * <p> |
82 * Objects that implement {@link RandomGenerator} are typically not cryptographically secure. |
84 * Objects that implement {@link RandomGenerator} are typically not cryptographically secure. |
83 * Consider instead using {@link java.security.SecureRandom} to get a cryptographically secure |
85 * Consider instead using {@link java.security.SecureRandom} to get a cryptographically secure |
84 * pseudorandom number generator for use by security-sensitive applications. Note, however, that |
86 * pseudorandom number generator for use by security-sensitive applications. Note, however, that |
85 * {@code java.security.SecureRandom} does implement the {@link RandomGenerator} interface, so that |
87 * {@code java.security.SecureRandom} does implement the {@link RandomGenerator} interface, so that |
89 * @since 14 |
91 * @since 14 |
90 */ |
92 */ |
91 public interface RandomGenerator { |
93 public interface RandomGenerator { |
92 |
94 |
93 /** |
95 /** |
94 * Supported randpm number Algorithms. |
96 * Supported random number Algorithms. |
95 */ |
97 */ |
96 public enum Algorithm { |
98 public enum Algorithm { |
97 /** |
99 /** |
98 * L32X64MixRandom algorithm |
100 * L32X64MixRandom algorithm |
99 */ |
101 */ |
100 L32X64MixRandom("L32X64MixRandom"), |
102 L32X64MixRandom("L32X64MixRandom"), |
101 /** |
103 /** |
|
104 * L64X128MixRandom algorithm |
|
105 */ |
|
106 L64X128MixRandom("L64X128MixRandom"), |
|
107 /** |
|
108 * L64X128StarStarRandom algorithm |
|
109 */ |
|
110 L64X128StarStarRandom("L64X128StarStarRandom"), |
|
111 /** |
|
112 * L64X128PlusPlusRandom algorithm |
|
113 */ |
|
114 L64X128PlusPlusRandom("L64X128PlusPlusRandom"), |
|
115 /** |
|
116 * L64X256MixRandom algorithm |
|
117 */ |
|
118 L64X256MixRandom("L64X256MixRandom"), |
|
119 /** |
102 * L64X1024MixRandom algorithm |
120 * L64X1024MixRandom algorithm |
103 */ |
121 */ |
104 L64X1024MixRandom("L64X1024MixRandom"), |
122 L64X1024MixRandom("L64X1024MixRandom"), |
105 /** |
123 /** |
106 * L64X1024Random algorithm |
124 * L128X128MixRandom algorithm |
107 */ |
125 */ |
108 L64X1024Random("L64X1024Random"), |
126 L128X128MixRandom("L128X128MixRandom"), |
109 /** |
127 /** |
110 * L64X128MixRandom algorithm |
128 * L128X128StarStarRandom algorithm |
111 */ |
129 */ |
112 L64X128MixRandom("L64X128MixRandom"), |
130 L128X128StarStarRandom("L128X128StarStarRandom"), |
113 /** |
131 /** |
114 * L64X128Random algorithm |
132 * L128X128PlusPlusRandom algorithm |
115 */ |
133 */ |
116 L64X128Random("L64X128Random"), |
134 L128X128PlusPlusRandom("L128X128PlusPlusRandom"), |
117 /** |
|
118 * L64X256MixRandom algorithm |
|
119 */ |
|
120 L64X256MixRandom("L64X256MixRandom"), |
|
121 /** |
|
122 * L64X256Random algorithm |
|
123 */ |
|
124 L64X256Random("L64X256Random"), |
|
125 /** |
135 /** |
126 * L128X256MixRandom algorithm |
136 * L128X256MixRandom algorithm |
127 */ |
137 */ |
128 L128X256MixRandom("L128X256MixRandom"), |
138 L128X256MixRandom("L128X256MixRandom"), |
|
139 /** |
|
140 * L128X1024MixRandom algorithm |
|
141 */ |
|
142 L128X1024MixRandom("L128X1024MixRandom"), |
129 /** |
143 /** |
130 * MRG32k3a algorithm |
144 * MRG32k3a algorithm |
131 */ |
145 */ |
132 MRG32k3a("MRG32k3a"), |
146 MRG32k3a("MRG32k3a"), |
133 /** |
147 /** |
260 * @param randomNumberBound the upper bound (exclusive) for each value produced |
274 * @param randomNumberBound the upper bound (exclusive) for each value produced |
261 * |
275 * |
262 * @return a stream of pseudorandomly chosen {@code double} values, each between |
276 * @return a stream of pseudorandomly chosen {@code double} values, each between |
263 * the specified origin (inclusive) and the specified bound (exclusive) |
277 * the specified origin (inclusive) and the specified bound (exclusive) |
264 * |
278 * |
265 * @throws IllegalArgumentException if {@code randomNumberOrigin} |
279 * @throws IllegalArgumentException if {@code randomNumberOrigin} is not finite, |
|
280 * or {@code randomNumberBound} is not finite, or {@code randomNumberOrigin} |
266 * is greater than or equal to {@code randomNumberBound} |
281 * is greater than or equal to {@code randomNumberBound} |
267 * |
282 * |
268 * @implNote It is permitted to implement this method in a manner |
283 * @implNote It is permitted to implement this method in a manner equivalent to |
269 * equivalent to |
|
270 * {@code doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}. |
284 * {@code doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}. |
271 * @implNote The default implementation produces a sequential stream that repeatedly |
285 * @implNote The default implementation produces a sequential stream that repeatedly |
272 * calls {@code nextDouble(randomNumberOrigin, randomNumberBound)}. |
286 * calls {@code nextDouble(randomNumberOrigin, randomNumberBound)}. |
273 */ |
287 */ |
274 default DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) { |
288 default DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) { |
305 * @param randomNumberBound the upper bound (exclusive) for each value produced |
319 * @param randomNumberBound the upper bound (exclusive) for each value produced |
306 * |
320 * |
307 * @return a stream of pseudorandomly chosen {@code double} values, each between |
321 * @return a stream of pseudorandomly chosen {@code double} values, each between |
308 * the specified origin (inclusive) and the specified bound (exclusive) |
322 * the specified origin (inclusive) and the specified bound (exclusive) |
309 * |
323 * |
310 * @throws IllegalArgumentException if {@code streamSize} is |
324 * @throws IllegalArgumentException if {@code streamSize} is less than zero, |
311 * less than zero, or {@code randomNumberOrigin} |
325 * or {@code randomNumberOrigin} is not finite, |
|
326 * or {@code randomNumberBound} is not finite, or {@code randomNumberOrigin} |
312 * is greater than or equal to {@code randomNumberBound} |
327 * is greater than or equal to {@code randomNumberBound} |
313 * |
328 * |
314 * @implNote The default implementation produces a sequential stream |
329 * @implNote The default implementation produces a sequential stream that repeatedly |
315 * that repeatedly calls {@code nextDouble(randomNumberOrigin, randomNumberBound)}. |
330 * calls {@code nextDouble(randomNumberOrigin, randomNumberBound)}. |
316 */ |
331 */ |
317 default DoubleStream doubles(long streamSize, double randomNumberOrigin, |
332 default DoubleStream doubles(long streamSize, double randomNumberOrigin, |
318 double randomNumberBound) { |
333 double randomNumberBound) { |
319 RandomSupport.checkStreamSize(streamSize); |
334 RandomSupport.checkStreamSize(streamSize); |
320 RandomSupport.checkRange(randomNumberOrigin, randomNumberBound); |
335 RandomSupport.checkRange(randomNumberOrigin, randomNumberBound); |
321 return doubles(randomNumberOrigin, randomNumberBound).limit(streamSize); |
336 return doubles(randomNumberOrigin, randomNumberBound).limit(streamSize); |
322 } |
337 } |
323 |
338 |
326 * {@code int} values. |
341 * {@code int} values. |
327 * |
342 * |
328 * @return a stream of pseudorandomly chosen {@code int} values |
343 * @return a stream of pseudorandomly chosen {@code int} values |
329 * |
344 * |
330 * @implNote It is permitted to implement this method in a manner |
345 * @implNote It is permitted to implement this method in a manner |
331 * equivalent to {@code ints(Long.MAX_VALUE)}. |
346 * equivalent to {@code ints(Long.MAX_VALUE)}. |
332 * @implNote The default implementation produces a sequential stream |
347 * @implNote The default implementation produces a sequential stream |
333 * that repeatedly calls {@code nextInt()}. |
348 * that repeatedly calls {@code nextInt()}. |
334 */ |
349 */ |
335 default IntStream ints() { |
350 default IntStream ints() { |
336 return IntStream.generate(this::nextInt).sequential(); |
351 return IntStream.generate(this::nextInt).sequential(); |
337 } |
352 } |
338 |
353 |
397 * |
412 * |
398 * @implNote The default implementation produces a sequential stream that repeatedly |
413 * @implNote The default implementation produces a sequential stream that repeatedly |
399 * calls {@code nextInt(randomNumberOrigin, randomNumberBound)}. |
414 * calls {@code nextInt(randomNumberOrigin, randomNumberBound)}. |
400 */ |
415 */ |
401 default IntStream ints(long streamSize, int randomNumberOrigin, |
416 default IntStream ints(long streamSize, int randomNumberOrigin, |
402 int randomNumberBound) { |
417 int randomNumberBound) { |
403 RandomSupport.checkStreamSize(streamSize); |
418 RandomSupport.checkStreamSize(streamSize); |
404 RandomSupport.checkRange(randomNumberOrigin, randomNumberBound); |
419 RandomSupport.checkRange(randomNumberOrigin, randomNumberBound); |
405 return ints(randomNumberOrigin, randomNumberBound).limit(streamSize); |
420 return ints(randomNumberOrigin, randomNumberBound).limit(streamSize); |
406 } |
421 } |
407 |
422 |
432 * the specified origin (inclusive) and the specified bound (exclusive) |
447 * the specified origin (inclusive) and the specified bound (exclusive) |
433 * |
448 * |
434 * @throws IllegalArgumentException if {@code randomNumberOrigin} |
449 * @throws IllegalArgumentException if {@code randomNumberOrigin} |
435 * is greater than or equal to {@code randomNumberBound} |
450 * is greater than or equal to {@code randomNumberBound} |
436 * |
451 * |
437 * @implNote It is permitted to implement this method in a manner |
452 * @implNote It is permitted to implement this method in a manner equivalent to |
438 * equivalent to {@code longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}. |
453 * {@code longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}. |
439 * @implNote The default implementation produces a sequential stream that repeatedly |
454 * @implNote The default implementation produces a sequential stream that repeatedly |
440 * calls {@code nextLong(randomNumberOrigin, randomNumberBound)}. |
455 * calls {@code nextLong(randomNumberOrigin, randomNumberBound)}. |
441 */ |
456 */ |
442 default LongStream longs(long randomNumberOrigin, long randomNumberBound) { |
457 default LongStream longs(long randomNumberOrigin, long randomNumberBound) { |
443 RandomSupport.checkRange(randomNumberOrigin, randomNumberBound); |
458 RandomSupport.checkRange(randomNumberOrigin, randomNumberBound); |
481 * |
496 * |
482 * @implNote The default implementation produces a sequential stream that repeatedly |
497 * @implNote The default implementation produces a sequential stream that repeatedly |
483 * calls {@code nextLong(randomNumberOrigin, randomNumberBound)}. |
498 * calls {@code nextLong(randomNumberOrigin, randomNumberBound)}. |
484 */ |
499 */ |
485 default LongStream longs(long streamSize, long randomNumberOrigin, |
500 default LongStream longs(long streamSize, long randomNumberOrigin, |
486 long randomNumberBound) { |
501 long randomNumberBound) { |
487 RandomSupport.checkStreamSize(streamSize); |
502 RandomSupport.checkStreamSize(streamSize); |
488 RandomSupport.checkRange(randomNumberOrigin, randomNumberBound); |
503 RandomSupport.checkRange(randomNumberOrigin, randomNumberBound); |
489 return longs(randomNumberOrigin, randomNumberBound).limit(streamSize); |
504 return longs(randomNumberOrigin, randomNumberBound).limit(streamSize); |
490 } |
505 } |
491 |
506 |
492 /** |
507 /** |
493 * Returns a pseudorandomly chosen {@code boolean} value. |
508 * Returns a pseudorandomly chosen {@code boolean} value. |
494 * <p> |
509 * <p> |
495 * The default implementation tests the high-order bit (sign bit) of a value produced by {@code |
510 * The default implementation tests the high-order bit (sign bit) of a value produced by |
496 * nextInt()}, on the grounds that some algorithms for pseudorandom number generation produce |
511 * {@code nextInt()}, on the grounds that some algorithms for pseudorandom number generation |
497 * values whose high-order bits have better statistical quality than the low-order bits. |
512 * produce values whose high-order bits have better statistical quality than the low-order bits. |
498 * |
513 * |
499 * @return a pseudorandomly chosen {@code boolean} value |
514 * @return a pseudorandomly chosen {@code boolean} value |
500 */ |
515 */ |
501 default boolean nextBoolean() { |
516 default boolean nextBoolean() { |
502 return nextInt() < 0; |
517 return nextInt() < 0; |
522 * |
537 * |
523 * @return a pseudorandomly chosen {@code float} value between |
538 * @return a pseudorandomly chosen {@code float} value between |
524 * zero (inclusive) and the bound (exclusive) |
539 * zero (inclusive) and the bound (exclusive) |
525 * |
540 * |
526 * @throws IllegalArgumentException if {@code bound} is not |
541 * @throws IllegalArgumentException if {@code bound} is not |
527 * positive and finite |
542 * both positive and finite |
528 * |
543 * |
529 * @implNote The default implementation simply calls |
544 * @implNote The default implementation simply calls |
530 * {@code RandomSupport.checkBound(bound)} and then |
545 * {@code RandomSupport.checkBound(bound)} and then |
531 * {@code RandomSupport.boundedNextFloat(this, bound)}. |
546 * {@code RandomSupport.boundedNextFloat(this, bound)}. |
532 */ |
547 */ |
533 default float nextFloat(float bound) { |
548 default float nextFloat(float bound) { |
534 RandomSupport.checkBound(bound); |
549 RandomSupport.checkBound(bound); |
535 return RandomSupport.boundedNextFloat(this, bound); |
550 return RandomSupport.boundedNextFloat(this, bound); |
536 } |
551 } |
543 * @param bound the upper bound (exclusive) |
558 * @param bound the upper bound (exclusive) |
544 * |
559 * |
545 * @return a pseudorandomly chosen {@code float} value between the |
560 * @return a pseudorandomly chosen {@code float} value between the |
546 * origin (inclusive) and the bound (exclusive) |
561 * origin (inclusive) and the bound (exclusive) |
547 * |
562 * |
548 * @throws IllegalArgumentException unless {@code origin} is finite, |
563 * @throws IllegalArgumentException if {@code origin} is not finite, |
549 * {@code bound} is finite, and {@code origin} is less than |
564 * or {@code bound} is not finite, or {@code origin} |
550 * {@code bound} |
565 * is greater than or equal to {@code bound} |
551 * |
566 * |
552 * @implNote The default implementation simply calls |
567 * @implNote The default implementation simply calls |
553 * {@code RandomSupport.checkRange(origin, bound)} and then |
568 * {@code RandomSupport.checkRange(origin, bound)} and then |
554 * {@code RandomSupport.boundedNextFloat(this, origin, bound)}. |
569 * {@code RandomSupport.boundedNextFloat(this, origin, bound)}. |
555 */ |
570 */ |
556 default float nextFloat(float origin, float bound) { |
571 default float nextFloat(float origin, float bound) { |
557 RandomSupport.checkRange(origin, bound); |
572 RandomSupport.checkRange(origin, bound); |
558 return RandomSupport.boundedNextFloat(this, origin, bound); |
573 return RandomSupport.boundedNextFloat(this, origin, bound); |
559 } |
574 } |
578 * |
593 * |
579 * @return a pseudorandomly chosen {@code double} value between |
594 * @return a pseudorandomly chosen {@code double} value between |
580 * zero (inclusive) and the bound (exclusive) |
595 * zero (inclusive) and the bound (exclusive) |
581 * |
596 * |
582 * @throws IllegalArgumentException if {@code bound} is not |
597 * @throws IllegalArgumentException if {@code bound} is not |
583 * positive and finite |
598 * both positive and finite |
584 * |
599 * |
585 * @implNote The default implementation simply calls |
600 * @implNote The default implementation simply calls |
586 * {@code RandomSupport.checkBound(bound)} and then |
601 * {@code RandomSupport.checkBound(bound)} and then |
587 * {@code RandomSupport.boundedNextDouble(this, bound)}. |
602 * {@code RandomSupport.boundedNextDouble(this, bound)}. |
588 */ |
603 */ |
599 * @param bound the upper bound (exclusive) for the returned value |
614 * @param bound the upper bound (exclusive) for the returned value |
600 * |
615 * |
601 * @return a pseudorandomly chosen {@code double} value between the |
616 * @return a pseudorandomly chosen {@code double} value between the |
602 * origin (inclusive) and the bound (exclusive) |
617 * origin (inclusive) and the bound (exclusive) |
603 * |
618 * |
604 * @throws IllegalArgumentException unless {@code origin} is finite, |
619 * @throws IllegalArgumentException if {@code origin} is not finite, |
605 * {@code bound} is finite, and {@code origin} is less than |
620 * or {@code bound} is not finite, or {@code origin} |
606 * {@code bound} |
621 * is greater than or equal to {@code bound} |
607 * |
622 * |
608 * @implNote The default implementation simply calls |
623 * @implNote The default implementation simply calls |
609 * {@code RandomSupport.checkRange(origin, bound)} and then |
624 * {@code RandomSupport.checkRange(origin, bound)} and then |
610 * {@code RandomSupport.boundedNextDouble(this, origin, bound)}. |
625 * {@code RandomSupport.boundedNextDouble(this, origin, bound)}. |
611 */ |
626 */ |