Как сгенерировать случайное число в java
Содержание:
- Using Third-Party APIs
- Java Random Class
- Random Number Generation Using the Random Class
- Выбор случайного элемента из списка choice() модуль random
- ints(long streamSize)
- Secure Random Number – Best Practices
- Using Java API
- ints()
- Java Random Number Generator
- Using Apache Common lang
- Игра в кости с использованием модуля random в Python
- Core team and contributors
- Latest news
- What is Easy Random ?
- What is this EasyRandom API ?
- Why Easy Random ?
- Random Date
- Random Date and Time
- Random Time
- Вопрос 1. Что такое случайные числа?
- How can this be useful ?
- Псевдослучайные числа
- How can this be useful ?
Using Third-Party APIs
As we have seen, Java provides us with a lot of classes and methods for generating random numbers. However, there are also third-party APIs for this purpose.
We’re going to take a look at some of them.
3.1. org.apache.commons.math3.random.RandomDataGenerator
There are a lot of generators in the commons mathematics library from the Apache Commons project. The easiest, and probably the most useful, is the RandomDataGenerator. It uses the Well19937c algorithm for the random generation. However, we can provide our algorithm implementation.
Let’s see how to use it. Firstly, we have to add dependency:
The latest version of commons-math3 can be found on Maven Central.
Then we can start working with it:
3.2. it.unimi.dsi.util.XoRoShiRo128PlusRandom
Certainly, this is one of the fastest random number generator implementations. It has been developed at the Information Sciences Department of the Milan University.
The library is also available at Maven Central repositories. So, let’s add the dependency:
This generator inherits from java.util.Random. However, if we take a look at the JavaDoc, we realize that there’s only one way of using it — through the nextInt method. Above all, this method is only available with the zero- and one-parameter invocations. Any of the other invocations will directly use the java.util.Random methods.
For example, if we want to get a random number within a range, we would write:
Java Random Class
- class is part of java.util package.
- An instance of java Random class is used to generate random numbers.
- This class provides several methods to generate random numbers of type integer, double, long, float etc.
- Random number generation algorithm works on the seed value. If not provided, seed value is created from system nano time.
- If two Random instances have same seed value, then they will generate same sequence of random numbers.
- Java Random class is thread-safe, however in multithreaded environment it’s advised to use class.
- Random class instances are not suitable for security sensitive applications, better to use in those cases.
Java Random Constructors
Java Random class has two constructors which are given below:
- : creates new random generator
- : creates new random generator using specified seed
Java Random Class Methods
Let’s have a look at some of the methods of java Random class.
- : This method returns next pseudorandom which is a boolean value from random number generator sequence.
- : This method returns next pseudorandom which is double value between 0.0 and 1.0.
- : This method returns next pseudorandom which is float value between 0.0 and 1.0.
- : This method returns next int value from random number generator sequence.
- nextInt(int n): This method return a pseudorandom which is int value between 0 and specified value from random number generator sequence.
Java Random Example
Let’s have a look at the below java Random example program.
Output of the above program is:
Check this post for more about Java Radom Number Generation.
Generate Random Number using Seed
There are two ways we can generate random number using seed.
The seed is the initial value of the internal state of the pseudorandom number generator which is maintained by method next(int).
Output of the above program is:
What if we pass same seed to two different random number generators?
Let’s have a look at the below program and see what happen if we pass same seed to two different random number generators.
Output of the above program is:
We can see that it will generate same random number if we pass same seed to two different random number generators.
Java 8 Random Class Methods
As you can see from above image, there are many new methods added in Java 8 to Random class. These methods can produce a stream of random numbers. Below is a simple program to generate a stream of 5 integers between 1 and 100.
That’s all for a quick roundup on Java Random Class.
Reference: API Doc
Random Number Generation Using the Random Class
You can use the java.util.Random class to generate random numbers of different types, such as int, float, double, long, and boolean.
To generate random numbers, first, create an instance of the Random class and then call one of the random value generator methods, such as nextInt(), nextDouble(), or nextLong().
The nextInt() method of Random accepts a bound integer and returns a random integer from 0 (inclusive) to the specified bound (exclusive).
The code to use the nextInt() method is this.
The code to use the nextInt() method to generate an integer within a range is:
The nextFloat() and nextDouble() methods allow generating float and double values between 0.0 and 1.0.
The code to use both the methods is:
Выбор случайного элемента из списка choice() модуль random
Метод используется для выбора случайного элемента из списка. Набор может быть представлен в виде списка или python строки. Метод возвращает один случайный элемент последовательности.
Пример использования в Python:
Python
import random
list =
print(«random.choice используется для выбора случайного элемента из списка — «, random.choice(list))
1 2 3 4 5 |
importrandom list=55,66,77,88,99 print(«random.choice используется для выбора случайного элемента из списка — «,random.choice(list)) |
Вывод:
Shell
random.choice используется для выбора случайного элемента из списка — 55
1 | random.choiceиспользуетсядлявыбораслучайногоэлементаизсписка-55 |
ints(long streamSize)
Random.ints() returns a stream producing the given streamSize number of pseudorandom int values.
Syntax
The syntax of ints() method with stream size is
Random.ints(long streamSize)
where
Parameter | Description |
---|---|
streamSize | The number of values to generate in the stream. |
Returns
The method returns IntStream object.
Example 3 – ints(streamSize)
In this example, we will generate eight random integers using ints(streamSize) method and print out these random numbers from the stream to the console.
Java Program
import java.util.Random; import java.util.function.IntConsumer; import java.util.stream.IntStream; public class Example { public static void main(String[] args) { int streamSize = 8; Random random = new Random(); IntStream ds = random.ints(streamSize); ds.forEach(new IntConsumer() { @Override public void accept(int value) { System.out.println(value); } }); } }
Output
790793602 -445498747 -322809516 1575745272 732465345 586364815 1791511337 -1366525847
Secure Random Number – Best Practices
2.1. Determine performance criteria and workload balancing
If performance is a premier consideration, then use , which seeds from . SHA1PRNG can be 17 times faster than NativePRNG, but seeding options are fixed.
Seeding with is more flexible, but it blocks if entropy is not great enough on the server since it reads from . If you don’t know where to begin, start with .
2.2. Don’t accept defaults; specify the PRNG and the provider you want to use
Specify your criteria like this:
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "SUN");
Following is additional information about supported PRNGs and providers.
The following is a list of PRNGs for the SUN provider:
- SHA1PRNG (Initial seeding is currently done via a combination of system attributes and the java.security entropy gathering device)
- NativePRNG (nextBytes() uses /dev/urandom, generateSeed() uses /dev/random)
- NativePRNGBlocking (nextBytes() and generateSeed() use /dev/random)
- NativePRNGNonBlocking (nextBytes() and generateSeed() use /dev/urandom)
- NativePRNGBlocking and NativePRNGNonBlocking are available in JRE 8+.
For information on additional providers, see Java Cryptography Architecture Oracle Providers Documentation for JDK 8. Oracle also provides documentation describing the providers by OS platform.
2.3. Provide more opportunities increase entropy
Create a new instance of periodically and reseed, like this:
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "SUN"); sr.setSeed(SecureRandom.generateSeed(int))
Periodic reseeding defends against data disclosure if a seed is leaked. If using SHA1PRNG, always call immediately after creating a new instance of the PRNG.
2.4. Reduce predictability
If , a configuration parameter in the file, or the system property is assigned with a predictable file/URL, then SecureRandom can become predictable.
2.5. Patch old Java versions
JRE versions older than 1.4.2 have known problems generating SHA1PRNG secure seeds. Then again, if you’re using versions of Java this old, you have bigger security concerns.
Old versions of Java are very insecure, and staying up-to-date on patches is very important. One of the best ways to keep your customers safe is to quickly certify your software against the most recent Oracle Critical Patch Update possible.
Happy Learning !!
Using Java API
The Java API provides us with several ways to achieve our purpose. Let’s see some of them.
2.1. java.lang.Math
The random method of the Math class will return a double value in a range from 0.0 (inclusive) to 1.0 (exclusive). Let’s see how we’d use it to get a random number in a given range defined by min and max:
2.2. java.util.Random
Before Java 1.7, the most popular way of generating random numbers was using nextInt. There were two ways of using this method, with and without parameters. The no-parameter invocation returns any of the int values with approximately equal probability. So, it’s very likely that we’ll get negative numbers:
If we use the netxInt invocation with the bound parameter, we’ll get numbers within a range:
This will give us a number between 0 (inclusive) and parameter (exclusive). So, the bound parameter must be greater than 0. Otherwise, we’ll get a java.lang.IllegalArgumentException.
Java 8 introduced the new ints methods that return a java.util.stream.IntStream. Let’s see how to use them.
The ints method without parameters returns an unlimited stream of int values:
We can also pass in a single parameter to limit the stream size:
And, of course, we can set the maximum and minimum for the generated range:
2.3. java.util.concurrent.ThreadLocalRandom
Java 1.7 release brought us a new and more efficient way of generating random numbers via the ThreadLocalRandom class. This one has three important differences from the Random class:
- We don’t need to explicitly initiate a new instance of ThreadLocalRandom. This helps us to avoid mistakes of creating lots of useless instances and wasting garbage collector time
- We can’t set the seed for ThreadLocalRandom, which can lead to a real problem. If we need to set the seed, then we should avoid this way of generating random numbers
- Random class doesn’t perform well in multi-threaded environments
Now, let’s see how it works:
With Java 8 or above, we have new possibilities. Firstly, we have two variations for the nextInt method:
Secondly, and more importantly, we can use the ints method:
2.4. java.util.SplittableRandom
Java 8 has also brought us a really fast generator — the SplittableRandom class.
As we can see in the JavaDoc, this is a generator for use in parallel computations. It’s important to know that the instances are not thread-safe. So, we have to take care when using this class.
We have available the nextInt and ints methods. With nextInt we can set directly the top and bottom range using the two parameters invocation:
This way of using checks that the max parameter is bigger than min. Otherwise, we’ll get an IllegalArgumentException. However, it doesn’t check if we work with positive or negative numbers. So, any of the parameters can be negative. Also, we have available one- and zero-parameter invocations. Those work in the same way as we have described before.
We have available the ints methods, too. This means that we can easily get a stream of int values. To clarify, we can choose to have a limited or unlimited stream. For a limited stream, we can set the top and bottom for the number generation range:
2.5. java.security.SecureRandom
If we have security-sensitive applications, we should consider using SecureRandom. This is a cryptographically strong generator. Default-constructed instances don’t use cryptographically random seeds. So, we should either:
- Set the seed — consequently, the seed will be unpredictable
- Set the java.util.secureRandomSeed system property to true
This class inherits from java.util.Random. So, we have available all the methods we saw above. For example, if we need to get any of the int values, then we’ll call nextInt without parameters:
On the other hand, if we need to set the range, we can call it with the bound parameter:
We must remember that this way of using it throws IllegalArgumentException if the parameter is not bigger than zero.
ints()
Random.ints() returns an effectively unlimited stream of pseudorandom int values.
The syntax of ints() method is
Random.ints()
Returns
The method returns IntStream object.
Example 1 – ints()
In this example, we will generate an unlimited sequence of random integers using ints() method and print out four of them to the console.
Java Program
import java.util.Random; import java.util.stream.IntStream; import java.util.function.IntConsumer; public class Example { public static void main(String[] args) { Random random = new Random(); IntStream ds = random.ints(); ds.limit(4).forEach(new IntConsumer() { @Override public void accept(int value) { System.out.println(value); } }); } }
Output
1549243955 -654704097 -1217687007 1648661790
Java Random Number Generator
Let’s look at some examples to generate a random number in Java. Later on, we will also look at ThreadLocalRandom and SecureRandom example program.
1. Generate Random integer
Yes, it’s that simple to generate a random integer in java. When we create the Random instance, it generates a long seed value that is used in all the method calls. We can set this seed value in the program, however, it’s not required in most of the cases.
2. Java Random number between 1 and 10
Sometimes we have to generate a random number between a range. For example, in a dice game possible values can be between 1 to 6 only. Below is the code showing how to generate a random number between 1 and 10 inclusive.
The argument in the is excluded, so we have to provide argument as 11. Also, 0 is included in the generated random number, so we have to keep calling nextInt method until we get a value between 1 and 10. You can extend the above code to generate the random number within any given range.
7. Generate Random byte array
We can generate random bytes and place them into a user-supplied byte array using Random class. The number of random bytes produced is equal to the length of the byte array.
8. ThreadLocalRandom in multithreaded environment
Here is a simple example showing ThreadLocalRandom usage in a multithreaded environment.
Below is a sample output of my execution of the above program.
We can’t set seed value for ThreadLocalRandom instance, it will throw .
ThreadLocalRandom class also has some extra utility methods to generate a random number within a range. For example, to generate a random number between 1 and 10, we can do it like below.
ThreadLocalRandom has similar methods for generating random long and double values.
9. SecureRandom Example
You can use SecureRandom class to generate more secure random numbers using any of the listed providers. A quick SecureRandom example code is given below.
That’s all about generating a random number in Java program.
You can download the example code from our GitHub Repository.
Using Apache Common lang
You can use Apache Common lang to generate random String. It is quite easy to generate random String as you can use straight forward APIs to create random String.
Create AlphaNumericString
You can use RandomStringUtils.randomAlphanumeric method to generate alphanumeric random strn=ing.
1 |
packageorg.arpit.java2blog; import org.apache.commons.lang3.RandomStringUtils; publicclassApacheRandomStringMain{ publicstaticvoidmain(Stringargs){ System.out.println(«Generating String of length 10: «+RandomStringUtils.randomAlphanumeric(10)); System.out.println(«Generating String of length 10: «+RandomStringUtils.randomAlphanumeric(10)); System.out.println(«Generating String of length 10: «+RandomStringUtils.randomAlphanumeric(10)); } } |
Output:
Generating String of length 10: Wvxj2x385N
Generating String of length 10: urUnMHgAq9
Generating String of length 10: 8TddXvnDOV
Create random Alphabetic String
You can use RandomStringUtils.randomAlphabetic method to generate alphanumeric random strn=ing.
1 |
packageorg.arpit.java2blog; import org.apache.commons.lang3.RandomStringUtils; publicclassApacheRandomStringMain{ publicstaticvoidmain(Stringargs){ System.out.println(«Generating String of length 10: «+RandomStringUtils.randomAlphabetic(10)); System.out.println(«Generating String of length 10: «+RandomStringUtils.randomAlphabetic(10)); System.out.println(«Generating String of length 10: «+RandomStringUtils.randomAlphabetic(10)); } } |
Output:
Generating String of length 10: zebRkGDuNd
Generating String of length 10: RWQlXuGbTk
Generating String of length 10: mmXRopdapr
That’s all about generating Random String in java.
Игра в кости с использованием модуля random в Python
Далее представлен код простой игры в кости, которая поможет понять принцип работы функций модуля random. В игре два участника и два кубика.
- Участники по очереди бросают кубики, предварительно встряхнув их;
- Алгоритм высчитывает сумму значений кубиков каждого участника и добавляет полученный результат на доску с результатами;
- Участник, у которого в результате большее количество очков, выигрывает.
Код программы для игры в кости Python:
Python
import random
PlayerOne = «Анна»
PlayerTwo = «Алекс»
AnnaScore = 0
AlexScore = 0
# У каждого кубика шесть возможных значений
diceOne =
diceTwo =
def playDiceGame():
«»»Оба участника, Анна и Алекс, бросают кубик, используя метод shuffle»»»
for i in range(5):
#оба кубика встряхиваются 5 раз
random.shuffle(diceOne)
random.shuffle(diceTwo)
firstNumber = random.choice(diceOne) # использование метода choice для выбора случайного значения
SecondNumber = random.choice(diceTwo)
return firstNumber + SecondNumber
print(«Игра в кости использует модуль random\n»)
#Давайте сыграем в кости три раза
for i in range(3):
# определим, кто будет бросать кости первым
AlexTossNumber = random.randint(1, 100) # генерация случайного числа от 1 до 100, включая 100
AnnaTossNumber = random.randrange(1, 101, 1) # генерация случайного числа от 1 до 100, не включая 101
if( AlexTossNumber > AnnaTossNumber):
print(«Алекс выиграл жеребьевку.»)
AlexScore = playDiceGame()
AnnaScore = playDiceGame()
else:
print(«Анна выиграла жеребьевку.»)
AnnaScore = playDiceGame()
AlexScore = playDiceGame()
if(AlexScore > AnnaScore):
print («Алекс выиграл игру в кости. Финальный счет Алекса:», AlexScore, «Финальный счет Анны:», AnnaScore, «\n»)
else:
print(«Анна выиграла игру в кости. Финальный счет Анны:», AnnaScore, «Финальный счет Алекса:», AlexScore, «\n»)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
importrandom PlayerOne=»Анна» PlayerTwo=»Алекс» AnnaScore= AlexScore= diceOne=1,2,3,4,5,6 diceTwo=1,2,3,4,5,6 defplayDiceGame() «»»Оба участника, Анна и Алекс, бросают кубик, используя метод shuffle»»» foriinrange(5) #оба кубика встряхиваются 5 раз random.shuffle(diceOne) random.shuffle(diceTwo) firstNumber=random.choice(diceOne)# использование метода choice для выбора случайного значения SecondNumber=random.choice(diceTwo) returnfirstNumber+SecondNumber print(«Игра в кости использует модуль random\n») foriinrange(3) # определим, кто будет бросать кости первым AlexTossNumber=random.randint(1,100)# генерация случайного числа от 1 до 100, включая 100 AnnaTossNumber=random.randrange(1,101,1)# генерация случайного числа от 1 до 100, не включая 101 if(AlexTossNumber>AnnaTossNumber) print(«Алекс выиграл жеребьевку.») AlexScore=playDiceGame() AnnaScore=playDiceGame() else print(«Анна выиграла жеребьевку.») AnnaScore=playDiceGame() AlexScore=playDiceGame() if(AlexScore>AnnaScore) print(«Алекс выиграл игру в кости. Финальный счет Алекса:»,AlexScore,»Финальный счет Анны:»,AnnaScore,»\n») else print(«Анна выиграла игру в кости. Финальный счет Анны:»,AnnaScore,»Финальный счет Алекса:»,AlexScore,»\n») |
Вывод:
Shell
Игра в кости использует модуль random
Анна выиграла жеребьевку.
Анна выиграла игру в кости. Финальный счет Анны: 5 Финальный счет Алекса: 2
Анна выиграла жеребьевку.
Анна выиграла игру в кости. Финальный счет Анны: 10 Финальный счет Алекса: 2
Алекс выиграл жеребьевку.
Анна выиграла игру в кости. Финальный счет Анны: 10 Финальный счет Алекса: 8
1 2 3 4 5 6 7 8 9 10 |
Игравкостииспользуетмодульrandom Аннавыигралаигрувкости.ФинальныйсчетАнны5ФинальныйсчетАлекса2 Аннавыигралаигрувкости.ФинальныйсчетАнны10ФинальныйсчетАлекса2 Аннавыигралаигрувкости.ФинальныйсчетАнны10ФинальныйсчетАлекса8 |
Вот и все. Оставить комментарии можете в секции ниже.
Core team and contributors
Awesome contributors
- Adriano Machado
- Alberto Lagna
- Andrew Neal
- Aurélien Mino
- Arne Zelasko
- dadiyang
- Dovid Kopel
- Eric Taix
- euZebe
- Fred Eckertson
- huningd
- Johan Kindgren
- Joren Inghelbrecht
- Jose Manuel Prieto
- kermit-the-frog
- Lucas Andersson
- Michael Düsterhus
- Nikola Milivojevic
- nrenzoni
- Oleksandr Shcherbyna
- Petromir Dzhunev
- Rebecca McQuary
- Rodrigue Alcazar
- Ryan Dunckel
- Sam Van Overmeire
- Valters Vingolds
- Vincent Potucek
- Weronika Redlarska
- Konstantin Lutovich
- Steven_Van_Ophem
- Jean-Michel Leclercq
- Marian Jureczko
- Unconditional One
- JJ1216
- Sergey Chernov
Thank you all for your contributions!
Latest news
- 15/11/2020: Easy Random v5.0.0 is out and is now based on Java 11. Feature wise, this release is the same as v4.3.0. Please check the release notes for more details.
- 07/11/2020: Easy Random v4.3.0 is now released with support for generic types and fluent setters! You can find all details in the change log.
What is Easy Random ?
EasyRandom easyRandom = new EasyRandom(); Person person = easyRandom.nextObject(Person.class);
The method is able to generate random instances of any given type.
What is this EasyRandom API ?
The API provides 7 methods to generate random data: , , , , , and .
What if you need to generate a random ? Or say a random instance of your domain object?
Easy Random provides the API that extends with a method called .
This method is able to generate a random instance of any arbitrary Java bean.
The class is the main entry point to configure instances. It allows you to set all
parameters to control how random data is generated:
EasyRandomParameters parameters = new EasyRandomParameters() .seed(123L) .objectPoolSize(100) .randomizationDepth(3) .charset(forName("UTF-8")) .timeRange(nine, five) .dateRange(today, tomorrow) .stringLengthRange(5, 50) .collectionSizeRange(1, 10) .scanClasspathForConcreteTypes(true) .overrideDefaultInitialization(false) .ignoreRandomizationErrors(true); EasyRandom easyRandom = new EasyRandom(parameters);
For more details about these parameters, please refer to the configuration parameters section.
In most cases, default options are enough and you can use the default constructor of .
Easy Random allows you to control how to generate random data through the interface and makes it easy to exclude some fields from the object graph using a :
EasyRandomParameters parameters = new EasyRandomParameters() .randomize(String.class, () -> "foo") .excludeField(named("age").and(ofType(Integer.class)).and(inClass(Person.class))); EasyRandom easyRandom = new EasyRandom(parameters); Person person = easyRandom.nextObject(Person.class);
In the previous example, Easy Random will:
- Set all fields of type to (using the defined as a lambda expression)
- Exclude the field named of type in class .
The static methods , and are defined in
which provides common predicates you can use in combination to define exactly which fields to exclude.
A similar class called can be used to define which types to exclude from the object graph.
You can of course use your own in combination with those predefined predicates.
Why Easy Random ?
Populating a Java object with random data can look easy at first glance, unless your domain model involves many related classes. In the previous example, let’s suppose the type is defined as follows:
Without Easy Random, you would write the following code in order to create an instance of the class:
Street street = new Street(12, (byte) 1, "Oxford street"); Address address = new Address(street, "123456", "London", "United Kingdom"); Person person = new Person("Foo", "Bar", "foo.bar@gmail.com", Gender.MALE, address);
And if these classes do not provide constructors with parameters (may be some legacy beans you can’t change), you would write:
Street street = new Street(); street.setNumber(12); street.setType((byte) 1); street.setName("Oxford street"); Address address = new Address(); address.setStreet(street); address.setZipCode("123456"); address.setCity("London"); address.setCountry("United Kingdom"); Person person = new Person(); person.setFirstName("Foo"); person.setLastName("Bar"); person.setEmail("foo.bar@gmail.com"); person.setGender(Gender.MALE); person.setAddress(address);
With Easy Random, generating a random object is done with .
The library will recursively populate all the object graph. That’s a big difference!
Random Date
Up until now, we generated random temporals containing both date and time components. Similarly, we can use the concept of epoch days to generate random temporals with just date components.
An epoch day is equal to the number of days since the 1 January 1970. So in order to generate a random date, we just have to generate a random number and use that number as the epoch day.
3.1. Bounded
We need a temporal abstraction containing only date components, so java.time.LocalDate seems a good candidate:
Here we’re using the method to convert each LocalDate to its corresponding epoch day. Similarly, we can verify that this approach is correct:
3.2. Unbounded
In order to generate random dates regardless of any range, we can simply generate a random epoch day:
Our random date generator chooses a random day from 100 years before and after the epoch. Again, the rationale behind this is to generate reasonable date values:
Random Date and Time
Dates and times are nothing more than 32-bit integers compared to an epoch time, so we can generate random temporal values by following this simple algorithm:
- Generate a random 32-bit number, an int
- Pass the generated random value to an appropriate date and time constructor or builder
2.1. Bounded Instant
java.time.Instant is one of the new date and time additions in Java 8. They represent instantaneous points on the time-line.
In order to generate a random Instant between two other ones, we can:
- Generate a random number between the epoch seconds of the given Instants
- Create the random Instant by passing that random number to the method
In order to achieve more throughput in multi-threaded environments, we’re using the ThreadLocalRandom to generate our random numbers.
We can verify that the generated Instant is always greater than or equal to the first Instant and is less than the second Instant:
Remember, of course, that testing randomness is inherently non-deterministic and is generally not recommended in a real application.
Similarly, it’s also possible to generate a random Instant after or before another one:
2.2. Bounded Date
One of the java.util.Date constructors take the number of milliseconds after the epoch. So, we can use the same algorithm to generate a random Date between two others:
Similarly, we should be able to verify this behavior:
2.3. Unbounded Instant
In order to generate a totally random Instant, we can simply generate a random integer and pass it to the ofEpochSecond() method:
Using 32-bit seconds since the epoch time generates more reasonable random times, hence we’re using the nextInt() method here.
Also, this value should be still between the minimum and maximum possible Instant values that Java can handle:
2.4. Unbounded Date
Similar to the bounded example, we can pass a random value to Date’s constructor to generate a random Date:
Since the constructor’s time unit is milliseconds, we’re converting the 32-bit epoch seconds to milliseconds by multiplying it by 1000.
Certainly, this value is still between the minimum and maximum possible Date values:
Random Time
Similar to what we did with dates, we can generate random temporals with just time components. In order to do that, we can use the second of the day concept. That is, a random time is equal to a random number representing the seconds since the beginning of the day.
4.1. Bounded
The java.time.LocalTime class is a temporal abstraction that encapsulates nothing but time components:
In order to generate a random time between two others, we can:
- Generate a random number between the second of the day of the given times
- Create a random time using that random number
We can easily verify the behavior of this random time generation algorithm:
4.2. Unbounded
Even unbounded time values should be in 00:00:00 until 23:59:59 range, so we can simply implement this logic by delegation:
Вопрос 1. Что такое случайные числа?
Сложность: 1/3
Что нужно помнить: случайные числа — это математическое понятие, и их не следует путать с обыденными, произвольными числами. Случайное число в математике и программировании — это:
- число из определённого диапазона,
- у которого есть определённая вероятность выпадения.
Другими словами, существует закон или правило, которое называется «функцией распределения» или просто «распределением». И это самое распределение «раздаёт» каждому числу из диапазона определённую вероятность выпадения.
В качестве диапазона значений математикам и программистам привычнее всего использовать диапазон действительных чисел от 0 до 1, но это могут быть и целые числа от 1 до 6, как в игральном кубике, или от 100 до 1 000 000 — и так далее. Главное, что и распределение, и диапазон известны заранее, а само число нет.
Итого: случайные числа — это искусственно полученная последовательность чисел из определённого диапазона, которая подчиняется одному из законов распределения случайной величины.
How can this be useful ?
Sometimes, the test fixture does not really matter to the test logic. For example, if we want to test the result of a new sorting algorithm, we can generate random input data and assert the output is sorted, regardless of the data itself:
@org.junit.Test public void testSortAlgorithm() { // Given int[] ints = easyRandom.nextObject(int[].class); // When int[] sortedInts = myAwesomeSortAlgo.sort(ints); // Then assertThat(sortedInts).isSorted(); // fake assertion }
Another example is testing the persistence of a domain object, we can generate a random domain object, persist it and assert the database contains the same values:
@org.junit.Test public void testPersistPerson() throws Exception { // Given Person person = easyRandom.nextObject(Person.class); // When personDao.persist(person); // Then assertThat("person_table").column("name").value().isEqualTo(person.getName()); // assretj db }
There are many other uses cases where Easy Random can be useful, you can find a non exhaustive list in the wiki.
Псевдослучайные числа
Иногда программист сталкивается с простыми, казалось бы, задачами: «отобрать случайный фильм для вечернего просмотра из определенного списка», «выбрать победителя лотереи», «перемешать список песен при тряске смартфона», «выбрать случайное число для шифрования сообщения», и каждый раз у него возникает очень закономерный вопрос: а как получить это самое случайное число?
Вообще-то, если вам нужно получить «настоящее случайное число», сделать это довольно-таки трудно. Вплоть до того, что в компьютер встраивают специальные математические сопроцессоры, которые умеют генерировать такие числа, с выполнением всех требований к «истинной случайности».
Поэтому программисты придумали свое решение — псевдослучайные числа. Псевдослучайные числа — это некая последовательность, числа в которой на первый взгляд кажутся случайными, но специалист при детальном анализе сможет найти в них определенные закономерности. Для шифрования секретных документов такие числа не подойдут, а для имитации бросания кубика в игре — вполне.
Есть много алгоритмов генерации последовательности псевдослучайных чисел и почти все из них генерируют следующее случайное число на основе предыдущего и еще каких-то вспомогательных чисел.
Например, данная программа выведет на экран неповторяющихся чисел:
Кстати, мы говорим не о псевдослучайных числах, а именно о последовательности таких чисел. Т.к. глядя на одно число невозможно понять, случайное оно или нет.
Случайное число ведь можно получить разными способами:
How can this be useful ?
Sometimes, the test fixture does not really matter to the test logic. For example, if we want to test the result of a new sorting algorithm, we can generate random input data and assert the output is sorted, regardless of the data itself:
@org.junit.Test public void testSortAlgorithm() { // Given int[] ints = easyRandom.nextObject(int[].class); // When int[] sortedInts = myAwesomeSortAlgo.sort(ints); // Then assertThat(sortedInts).isSorted(); // fake assertion }
Another example is testing the persistence of a domain object, we can generate a random domain object, persist it and assert the database contains the same values:
@org.junit.Test public void testPersistPerson() throws Exception { // Given Person person = easyRandom.nextObject(Person.class); // When personDao.persist(person); // Then assertThat("person_table").column("name").value().isEqualTo(person.getName()); // assretj db }
There are many other uses cases where Easy Random can be useful, you can find a non exhaustive list in the wiki.