src/java.base/share/classes/java/util/random/AbstractSpliteratorRNG.java
branchJDK-8193209-branch
changeset 57547 56cbdc3ea079
parent 57546 1ca1cfdcb451
child 57671 6a4be8bf8990
equal deleted inserted replaced
57546:1ca1cfdcb451 57547:56cbdc3ea079
     1 /*
       
     2  * Copyright (c) 2013, 2019, Oraclea and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 package java.util.random;
       
    27 
       
    28 import java.util.Spliterator;
       
    29 import java.util.stream.Stream;
       
    30 import java.util.stream.DoubleStream;
       
    31 import java.util.stream.IntStream;
       
    32 import java.util.stream.LongStream;
       
    33 import java.util.stream.StreamSupport;
       
    34 
       
    35 /**
       
    36  * This class overrides the stream-producing methods (such as {@code ints()})
       
    37  * in class {@link AbstractRNG} to provide {@link Spliterator}-based
       
    38  * implmentations that support potentially parallel execution.
       
    39  *
       
    40  * To implement a pseudorandom number generator, the programmer needs
       
    41  * only to extend this class and provide implementations for the methods
       
    42  * {@code nextInt()}, {@code nextLong()}, {@code makeIntsSpliterator},
       
    43  * {@code makeLongsSpliterator}, and {@code makeDoublesSpliterator}.
       
    44  *
       
    45  * This class is not public; it provides shared code to the public
       
    46  * classes {@link AbstractSplittableRNG}, {@link AbstractSharedRNG},
       
    47  * and {@link AbstractArbitrarilyJumpableRNG}.
       
    48  *
       
    49  * @since 14
       
    50  */
       
    51 
       
    52 abstract class AbstractSpliteratorRNG implements RandomNumberGenerator {
       
    53     /*
       
    54      * Implementation Overview.
       
    55      *
       
    56      * This class provides most of the "user API" methods needed to
       
    57      * satisfy the interface RandomNumberGenerator.  An implementation of this
       
    58      * interface need only extend this class and provide implementations
       
    59      * of six methods: nextInt, nextLong, and nextDouble (the versions
       
    60      * that take no arguments) and makeIntsSpliterator,
       
    61      * makeLongsSpliterator, and makeDoublesSpliterator.
       
    62      *
       
    63      * File organization: First the non-public abstract methods needed
       
    64      * to create spliterators, then the main public methods.
       
    65      */
       
    66 
       
    67     abstract Spliterator.OfInt makeIntsSpliterator(long index, long fence, int origin, int bound);
       
    68     abstract Spliterator.OfLong makeLongsSpliterator(long index, long fence, long origin, long bound);
       
    69     abstract Spliterator.OfDouble makeDoublesSpliterator(long index, long fence, double origin, double bound);
       
    70 
       
    71     /* ---------------- public methods ---------------- */
       
    72 
       
    73     // stream methods, coded in a way intended to better isolate for
       
    74     // maintenance purposes the small differences across forms.
       
    75 
       
    76     private static IntStream intStream(Spliterator.OfInt srng) {
       
    77         return StreamSupport.intStream(srng, false);
       
    78     }
       
    79 
       
    80     private static LongStream longStream(Spliterator.OfLong srng) {
       
    81         return StreamSupport.longStream(srng, false);
       
    82     }
       
    83 
       
    84     private static DoubleStream doubleStream(Spliterator.OfDouble srng) {
       
    85         return StreamSupport.doubleStream(srng, false);
       
    86     }
       
    87 
       
    88     /**
       
    89      * Returns a stream producing the given {@code streamSize} number of pseudorandom {@code int}
       
    90      * values from this generator and/or one split from it.
       
    91      *
       
    92      * @param streamSize the number of values to generate
       
    93      *
       
    94      * @return a stream of pseudorandom {@code int} values
       
    95      *
       
    96      * @throws IllegalArgumentException if {@code streamSize} is less than zero
       
    97      */
       
    98     public IntStream ints(long streamSize) {
       
    99         RNGSupport.checkStreamSize(streamSize);
       
   100         return intStream(makeIntsSpliterator(0L, streamSize, Integer.MAX_VALUE, 0));
       
   101     }
       
   102 
       
   103     /**
       
   104      * Returns an effectively unlimited stream of pseudorandomly chosen
       
   105      * {@code int} values.
       
   106      *
       
   107      * @implNote The implementation of this method is effectively
       
   108      * equivalent to {@code ints(Long.MAX_VALUE)}.
       
   109      *
       
   110      * @return a stream of pseudorandomly chosen {@code int} values
       
   111      */
       
   112 
       
   113     public IntStream ints() {
       
   114         return intStream(makeIntsSpliterator(0L, Long.MAX_VALUE, Integer.MAX_VALUE, 0));
       
   115     }
       
   116 
       
   117     /**
       
   118      * Returns a stream producing the given {@code streamSize} number of pseudorandom {@code int}
       
   119      * values from this generator and/or one split from it; each value conforms to the given origin
       
   120      * (inclusive) and bound (exclusive).
       
   121      *
       
   122      * @param streamSize         the number of values to generate
       
   123      * @param randomNumberOrigin the origin (inclusive) of each random value
       
   124      * @param randomNumberBound  the bound (exclusive) of each random value
       
   125      *
       
   126      * @return a stream of pseudorandom {@code int} values, each with the given origin (inclusive)
       
   127      *         and bound (exclusive)
       
   128      *
       
   129      * @throws IllegalArgumentException if {@code streamSize} is less than zero, or {@code
       
   130      *                                  randomNumberOrigin} is greater than or equal to {@code
       
   131      *                                  randomNumberBound}
       
   132      */
       
   133     public IntStream ints(long streamSize, int randomNumberOrigin, int randomNumberBound) {
       
   134         RNGSupport.checkStreamSize(streamSize);
       
   135         RNGSupport.checkRange(randomNumberOrigin, randomNumberBound);
       
   136         return intStream(makeIntsSpliterator(0L, streamSize, randomNumberOrigin, randomNumberBound));
       
   137     }
       
   138 
       
   139     /**
       
   140      * Returns an effectively unlimited stream of pseudorandom {@code int} values from this
       
   141      * generator and/or one split from it; each value conforms to the given origin (inclusive) and
       
   142      * bound (exclusive).
       
   143      *
       
   144      * @param randomNumberOrigin the origin (inclusive) of each random value
       
   145      * @param randomNumberBound  the bound (exclusive) of each random value
       
   146      *
       
   147      * @return a stream of pseudorandom {@code int} values, each with the given origin (inclusive)
       
   148      *         and bound (exclusive)
       
   149      *
       
   150      * @throws IllegalArgumentException if {@code randomNumberOrigin} is greater than or equal to
       
   151      *                                  {@code randomNumberBound}
       
   152      *
       
   153      * @implNote This method is implemented to be equivalent to {@code ints(Long.MAX_VALUE,
       
   154      *         randomNumberOrigin, randomNumberBound)}.
       
   155      */
       
   156     public IntStream ints(int randomNumberOrigin, int randomNumberBound) {
       
   157         RNGSupport.checkRange(randomNumberOrigin, randomNumberBound);
       
   158         return intStream(makeIntsSpliterator(0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound));
       
   159     }
       
   160 
       
   161     /**
       
   162      * Returns a stream producing the given {@code streamSize} number of pseudorandom {@code long}
       
   163      * values from this generator and/or one split from it.
       
   164      *
       
   165      * @param streamSize the number of values to generate
       
   166      *
       
   167      * @return a stream of pseudorandom {@code long} values
       
   168      *
       
   169      * @throws IllegalArgumentException if {@code streamSize} is less than zero
       
   170      */
       
   171     public LongStream longs(long streamSize) {
       
   172         RNGSupport.checkStreamSize(streamSize);
       
   173         return longStream(makeLongsSpliterator(0L, streamSize, Long.MAX_VALUE, 0L));
       
   174     }
       
   175 
       
   176     /**
       
   177      * Returns an effectively unlimited stream of pseudorandom {@code long} values from this
       
   178      * generator and/or one split from it.
       
   179      *
       
   180      * @return a stream of pseudorandom {@code long} values
       
   181      *
       
   182      * @implNote This method is implemented to be equivalent to {@code
       
   183      *         longs(Long.MAX_VALUE)}.
       
   184      */
       
   185     public LongStream longs() {
       
   186         return longStream(makeLongsSpliterator(0L, Long.MAX_VALUE, Long.MAX_VALUE, 0L));
       
   187     }
       
   188 
       
   189     /**
       
   190      * Returns a stream producing the given {@code streamSize} number of pseudorandom {@code long}
       
   191      * values from this generator and/or one split from it; each value conforms to the given origin
       
   192      * (inclusive) and bound (exclusive).
       
   193      *
       
   194      * @param streamSize         the number of values to generate
       
   195      * @param randomNumberOrigin the origin (inclusive) of each random value
       
   196      * @param randomNumberBound  the bound (exclusive) of each random value
       
   197      *
       
   198      * @return a stream of pseudorandom {@code long} values, each with the given origin (inclusive)
       
   199      *         and bound (exclusive)
       
   200      *
       
   201      * @throws IllegalArgumentException if {@code streamSize} is less than zero, or {@code
       
   202      *                                  randomNumberOrigin} is greater than or equal to {@code
       
   203      *                                  randomNumberBound}
       
   204      */
       
   205     public LongStream longs(long streamSize, long randomNumberOrigin,
       
   206                              long randomNumberBound) {
       
   207         RNGSupport.checkStreamSize(streamSize);
       
   208         RNGSupport.checkRange(randomNumberOrigin, randomNumberBound);
       
   209         return longStream(makeLongsSpliterator(0L, streamSize, randomNumberOrigin, randomNumberBound));
       
   210     }
       
   211 
       
   212     /**
       
   213      * Returns an effectively unlimited stream of pseudorandom {@code long} values from this
       
   214      * generator and/or one split from it; each value conforms to the given origin (inclusive) and
       
   215      * bound (exclusive).
       
   216      *
       
   217      * @param randomNumberOrigin the origin (inclusive) of each random value
       
   218      * @param randomNumberBound  the bound (exclusive) of each random value
       
   219      *
       
   220      * @return a stream of pseudorandom {@code long} values, each with the given origin (inclusive)
       
   221      *         and bound (exclusive)
       
   222      *
       
   223      * @throws IllegalArgumentException if {@code randomNumberOrigin} is greater than or equal to
       
   224      *                                  {@code randomNumberBound}
       
   225      *
       
   226      * @implNote This method is implemented to be equivalent to {@code longs(Long.MAX_VALUE,
       
   227      *         randomNumberOrigin, randomNumberBound)}.
       
   228      */
       
   229     public LongStream longs(long randomNumberOrigin, long randomNumberBound) {
       
   230         RNGSupport.checkRange(randomNumberOrigin, randomNumberBound);
       
   231         return StreamSupport.longStream
       
   232             (makeLongsSpliterator(0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
       
   233              false);
       
   234     }
       
   235 
       
   236     /**
       
   237      * Returns a stream producing the given {@code streamSize} number of pseudorandom {@code double}
       
   238      * values from this generator and/or one split from it; each value is between zero (inclusive)
       
   239      * and one (exclusive).
       
   240      *
       
   241      * @param streamSize the number of values to generate
       
   242      *
       
   243      * @return a stream of {@code double} values
       
   244      *
       
   245      * @throws IllegalArgumentException if {@code streamSize} is less than zero
       
   246      */
       
   247     public DoubleStream doubles(long streamSize) {
       
   248         RNGSupport.checkStreamSize(streamSize);
       
   249         return doubleStream(makeDoublesSpliterator(0L, streamSize, Double.MAX_VALUE, 0.0));
       
   250     }
       
   251 
       
   252     /**
       
   253      * Returns an effectively unlimited stream of pseudorandom {@code double} values from this
       
   254      * generator and/or one split from it; each value is between zero (inclusive) and one
       
   255      * (exclusive).
       
   256      *
       
   257      * @return a stream of pseudorandom {@code double} values
       
   258      *
       
   259      * @implNote This method is implemented to be equivalent to {@code
       
   260      *         doubles(Long.MAX_VALUE)}.
       
   261      */
       
   262     public DoubleStream doubles() {
       
   263         return doubleStream(makeDoublesSpliterator(0L, Long.MAX_VALUE, Double.MAX_VALUE, 0.0));
       
   264     }
       
   265 
       
   266     /**
       
   267      * Returns a stream producing the given {@code streamSize} number of pseudorandom {@code double}
       
   268      * values from this generator and/or one split from it; each value conforms to the given origin
       
   269      * (inclusive) and bound (exclusive).
       
   270      *
       
   271      * @param streamSize         the number of values to generate
       
   272      * @param randomNumberOrigin the origin (inclusive) of each random value
       
   273      * @param randomNumberBound  the bound (exclusive) of each random value
       
   274      *
       
   275      * @return a stream of pseudorandom {@code double} values, each with the given origin
       
   276      *         (inclusive) and bound (exclusive)
       
   277      *
       
   278      * @throws IllegalArgumentException if {@code streamSize} is less than zero
       
   279      * @throws IllegalArgumentException if {@code randomNumberOrigin} is greater than or equal to
       
   280      *                                  {@code randomNumberBound}
       
   281      */
       
   282     public DoubleStream doubles(long streamSize, double randomNumberOrigin, double randomNumberBound) {
       
   283         RNGSupport.checkStreamSize(streamSize);
       
   284         RNGSupport.checkRange(randomNumberOrigin, randomNumberBound);
       
   285         return doubleStream(makeDoublesSpliterator(0L, streamSize, randomNumberOrigin, randomNumberBound));
       
   286     }
       
   287 
       
   288     /**
       
   289      * Returns an effectively unlimited stream of pseudorandom {@code double} values from this
       
   290      * generator and/or one split from it; each value conforms to the given origin (inclusive) and
       
   291      * bound (exclusive).
       
   292      *
       
   293      * @param randomNumberOrigin the origin (inclusive) of each random value
       
   294      * @param randomNumberBound  the bound (exclusive) of each random value
       
   295      *
       
   296      * @return a stream of pseudorandom {@code double} values, each with the given origin
       
   297      *         (inclusive) and bound (exclusive)
       
   298      *
       
   299      * @throws IllegalArgumentException if {@code randomNumberOrigin} is greater than or equal to
       
   300      *                                  {@code randomNumberBound}
       
   301      *
       
   302      * @implNote This method is implemented to be equivalent to {@code
       
   303      *         doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
       
   304      */
       
   305     public DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {
       
   306         RNGSupport.checkRange(randomNumberOrigin, randomNumberBound);
       
   307         return doubleStream(makeDoublesSpliterator(0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound));
       
   308     }
       
   309 
       
   310 }