I\'m trying to get random numbers between 0 and 100. But I want them to be unique, not repeated in a sequence. For example if I got 5 numbers, they should be 82,12,53,64,32
Use Collections.shuffle()
on all 100 numbers and select the first five, as shown here.
One clever way to do this is to use exponents of a primitive element in modulus.
For example, 2 is a primitive root mod 101, meaning that the powers of 2 mod 101 give you a non-repeating sequence that sees every number from 1 to 100 inclusive:
2^0 mod 101 = 1
2^1 mod 101 = 2
2^2 mod 101 = 4
...
2^50 mod 101 = 100
2^51 mod 101 = 99
2^52 mod 101 = 97
...
2^100 mod 101 = 1
In Java code, you would write:
void randInts() {
int num=1;
for (int ii=0; ii<101; ii++) {
System.out.println(num);
num= (num*2) % 101;
}
}
Finding a primitive root for a specific modulus can be tricky, but Maple's "primroot" function will do this for you.
you can use boolean array to fill the true if value taken else set navigate through boolean array to get value as per given below
package study;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/*
Created By Sachin Rane on Jul 18, 2018
*/
public class UniqueRandomNumber {
static Boolean[] boolArray;
public static void main(String s[]){
List<Integer> integers = new ArrayList<>();
for (int i = 0; i < 10; i++) {
integers.add(i);
}
//get unique random numbers
boolArray = new Boolean[integers.size()+1];
Arrays.fill(boolArray, false);
for (int i = 0; i < 10; i++) {
System.out.print(getUniqueRandomNumber(integers) + " ");
}
}
private static int getUniqueRandomNumber(List<Integer> integers) {
int randNum =(int) (Math.random()*integers.size());
if(boolArray[randNum]){
while(boolArray[randNum]){
randNum++;
if(randNum>boolArray.length){
randNum=0;
}
}
boolArray[randNum]=true;
return randNum;
}else {
boolArray[randNum]=true;
return randNum;
}
}
}
With Java 8+ you can use the ints method of Random
to get an IntStream of random values then distinct and limit to reduce the stream to a number of unique random values.
ThreadLocalRandom.current().ints(0, 100).distinct().limit(5).forEach(System.out::println);
Random
also has methods which create LongStream
s and DoubleStream
s if you need those instead.
If you want all (or a large amount) of the numbers in a range in a random order it might be more efficient to add all of the numbers to a list, shuffle it, and take the first n because the above example is currently implemented by generating random numbers in the range requested and passing them through a set (similarly to Rob Kielty's answer), which may require generating many more than the amount passed to limit because the probability of a generating a new unique number decreases with each one found. Here's an example of the other way:
List<Integer> range = IntStream.range(0, 100).boxed()
.collect(Collectors.toCollection(ArrayList::new));
Collections.shuffle(range);
range.subList(0, 99).forEach(System.out::println);
Below is a way I used to generate unique number always. Random function generates number and stores it in textfile then next time it checks it in file compares it and generate new unique number hence in this way there is always a new unique number.
public int GenerateRandomNo()
{
int _min = 0000;
int _max = 9999;
Random _rdm = new Random();
return _rdm.Next(_min, _max);
}
public int rand_num()
{
randnum = GenerateRandomNo();
string createText = randnum.ToString() + Environment.NewLine;
string file_path = System.IO.Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) + @"\Invoices\numbers.txt";
File.AppendAllText(file_path, createText);
int number = File.ReadLines(file_path).Count(); //count number of lines in file
System.IO.StreamReader file = new System.IO.StreamReader(file_path);
do
{
randnum = GenerateRandomNo();
}
while ((file.ReadLine()) == randnum.ToString());
file.Close();
return randnum;
}
This is the most simple method to generate unique random values in a range or from an array.
In this example, I will be using a predefined array but you can adapt this method to generate random numbers as well. First, we will create a sample array to retrieve our data from.
ArrayList<Integer> sampleList = new ArrayList<>();
sampleList.add(1);
sampleList.add(2);
sampleList.add(3);
sampleList.add(4);
sampleList.add(5);
sampleList.add(6);
sampleList.add(7);
sampleList.add(8);
Now from the sampleList
we will produce five random numbers that are unique.
int n;
randomList = new ArrayList<>();
for(int i=0;i<5;i++){
Random random = new Random();
n=random.nextInt(8); //Generate a random index between 0-7
if(!randomList.contains(sampleList.get(n)))
randomList.add(sampleList.get(n));
else
i--; //reiterating the step
}
This is conceptually very simple. If the random value generated already exists then we will reiterate the step. This will continue until all the values generated are unique.
If you found this answer useful then you can vote it up as it is much simple in concept as compared to the other answers.