View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.lang3;
18  
19  import java.util.Random;
20  import java.util.concurrent.ThreadLocalRandom;
21  
22  /**
23   * Utility library that supplements the standard {@link Random} class.
24   *
25   * <p>Caveat: Instances of {@link Random} are not cryptographically secure.</p>
26   *
27   * <p>Please note that the Apache Commons project provides a component
28   * dedicated to pseudo-random number generation, namely
29   * <a href="https://commons.apache.org/proper/commons-rng/">Commons RNG</a>, that may be
30   * a better choice for applications with more stringent requirements
31   * (performance and/or correctness).</p>
32   *
33   * @deprecated Use Apache Commons RNG's optimized <a href="https://commons.apache.org/proper/commons-rng/commons-rng-client-api/apidocs/org/apache/commons/rng/UniformRandomProvider.html">UniformRandomProvider</a>
34   * @since 3.3
35   */
36  @Deprecated
37  public class RandomUtils {
38  
39      /**
40       * Generates a random boolean value.
41       *
42       * @return the random boolean
43       * @since 3.5
44       */
45      public static boolean nextBoolean() {
46          return random().nextBoolean();
47      }
48  
49      /**
50       * Generates an array of random bytes.
51       *
52       * @param count
53       *            the size of the returned array
54       * @return the random byte array
55       * @throws IllegalArgumentException if {@code count} is negative
56       */
57      public static byte[] nextBytes(final int count) {
58          Validate.isTrue(count >= 0, "Count cannot be negative.");
59  
60          final byte[] result = new byte[count];
61          random().nextBytes(result);
62          return result;
63      }
64  
65      /**
66       * Generates a random double between 0 (inclusive) and Double.MAX_VALUE (exclusive).
67       *
68       * @return the random double
69       * @see #nextDouble(double, double)
70       * @since 3.5
71       */
72      public static double nextDouble() {
73          return nextDouble(0, Double.MAX_VALUE);
74      }
75  
76      /**
77       * Generates a random double within the specified range.
78       *
79       * @param startInclusive
80       *            the smallest value that can be returned, must be non-negative
81       * @param endExclusive
82       *            the upper bound (not included)
83       * @throws IllegalArgumentException
84       *             if {@code startInclusive > endExclusive} or if
85       *             {@code startInclusive} is negative
86       * @return the random double
87       */
88      public static double nextDouble(final double startInclusive, final double endExclusive) {
89          Validate.isTrue(endExclusive >= startInclusive,
90                  "Start value must be smaller or equal to end value.");
91          Validate.isTrue(startInclusive >= 0, "Both range values must be non-negative.");
92  
93          if (startInclusive == endExclusive) {
94              return startInclusive;
95          }
96  
97          return startInclusive + ((endExclusive - startInclusive) * random().nextDouble());
98      }
99  
100     /**
101      * Generates a random float between 0 (inclusive) and Float.MAX_VALUE (exclusive).
102      *
103      * @return the random float
104      * @see #nextFloat(float, float)
105      * @since 3.5
106      */
107     public static float nextFloat() {
108         return nextFloat(0, Float.MAX_VALUE);
109     }
110 
111     /**
112      * Generates a random float within the specified range.
113      *
114      * @param startInclusive
115      *            the smallest value that can be returned, must be non-negative
116      * @param endExclusive
117      *            the upper bound (not included)
118      * @throws IllegalArgumentException
119      *             if {@code startInclusive > endExclusive} or if
120      *             {@code startInclusive} is negative
121      * @return the random float
122      */
123     public static float nextFloat(final float startInclusive, final float endExclusive) {
124         Validate.isTrue(endExclusive >= startInclusive,
125                 "Start value must be smaller or equal to end value.");
126         Validate.isTrue(startInclusive >= 0, "Both range values must be non-negative.");
127 
128         if (startInclusive == endExclusive) {
129             return startInclusive;
130         }
131 
132         return startInclusive + ((endExclusive - startInclusive) * random().nextFloat());
133     }
134 
135     /**
136      * Generates a random int between 0 (inclusive) and Integer.MAX_VALUE (exclusive).
137      *
138      * @return the random integer
139      * @see #nextInt(int, int)
140      * @since 3.5
141      */
142     public static int nextInt() {
143         return nextInt(0, Integer.MAX_VALUE);
144     }
145 
146     /**
147      * Generates a random integer within the specified range.
148      *
149      * @param startInclusive
150      *            the smallest value that can be returned, must be non-negative
151      * @param endExclusive
152      *            the upper bound (not included)
153      * @throws IllegalArgumentException
154      *             if {@code startInclusive > endExclusive} or if
155      *             {@code startInclusive} is negative
156      * @return the random integer
157      */
158     public static int nextInt(final int startInclusive, final int endExclusive) {
159         Validate.isTrue(endExclusive >= startInclusive,
160                 "Start value must be smaller or equal to end value.");
161         Validate.isTrue(startInclusive >= 0, "Both range values must be non-negative.");
162 
163         if (startInclusive == endExclusive) {
164             return startInclusive;
165         }
166 
167         return startInclusive + random().nextInt(endExclusive - startInclusive);
168     }
169 
170     /**
171      * Generates a random long between 0 (inclusive) and Long.MAX_VALUE (exclusive).
172      *
173      * @return the random long
174      * @see #nextLong(long, long)
175      * @since 3.5
176      */
177     public static long nextLong() {
178         return nextLong(Long.MAX_VALUE);
179     }
180 
181     /**
182      * Generates a {@code long} value between 0 (inclusive) and the specified
183      * value (exclusive).
184      *
185      * @param n Bound on the random number to be returned.  Must be positive.
186      * @return a random {@code long} value between 0 (inclusive) and {@code n}
187      * (exclusive).
188      */
189     private static long nextLong(final long n) {
190         // Extracted from o.a.c.rng.core.BaseProvider.nextLong(long)
191         long bits;
192         long val;
193         do {
194             bits = random().nextLong() >>> 1;
195             val  = bits % n;
196         } while (bits - val + (n - 1) < 0);
197 
198         return val;
199     }
200 
201     /**
202      * Generates a random long within the specified range.
203      *
204      * @param startInclusive
205      *            the smallest value that can be returned, must be non-negative
206      * @param endExclusive
207      *            the upper bound (not included)
208      * @throws IllegalArgumentException
209      *             if {@code startInclusive > endExclusive} or if
210      *             {@code startInclusive} is negative
211      * @return the random long
212      */
213     public static long nextLong(final long startInclusive, final long endExclusive) {
214         Validate.isTrue(endExclusive >= startInclusive,
215                 "Start value must be smaller or equal to end value.");
216         Validate.isTrue(startInclusive >= 0, "Both range values must be non-negative.");
217 
218         if (startInclusive == endExclusive) {
219             return startInclusive;
220         }
221 
222         return startInclusive + nextLong(endExclusive - startInclusive);
223     }
224 
225     private static ThreadLocalRandom random() {
226         return ThreadLocalRandom.current();
227     }
228 
229     /**
230      * {@link RandomUtils} instances should NOT be constructed in standard
231      * programming. Instead, the class should be used as
232      * {@code RandomUtils.nextBytes(5);}.
233      * <p>
234      * This constructor is public to permit tools that require a JavaBean
235      * instance to operate.
236      * </p>
237      */
238     public RandomUtils() {
239     }
240 }