Better way to generate unique random numbers in Java - java

I need unique random ints in specified range. I use this approch:
class Main
{
static final int RANGE = 100;
static int uniqueGenerator(int range_, boolean boolArr_[], Random rand_)
{
int tmpVar = rand_.nextInt(range_);
while (boolArr_[tmpVar] == true)
{
tmpVar = rand.nextInt(range_);
}
boolArr_[tmpVar] = true;
return tmpVar;
}
public static void main(String[] args)
{
Random rand = new Random();
boolean boolArr[] = new boolean[RANGE];
Arrays.fill(boolArr, false);
int ceiling = 10;
int tmp = Main.uniqueGenerator(ceiling, boolArr, rand);
System.out.println(tmp); => 5
ceiling = 20;
tmp = Main.uniqueGenerator(ceiling, boolArr);
System.out.println(tmp); => 17
}
}
It seems to be cumbersome. Maybe someone knows better approach?
EDIT: I use it in game code, so I need most efficient solution. Answers below suggest initializing new list, shuffling it => too resource consuming/need to generate new list every time when need to change range.

List<Integer> list = new ArrayList<Integer>();
for(int i = 1; i <= 100; i++) list.add(i);
Collections.shuffle(list);

Fill an array with the range of numbers you want, shuffle it and extract an item.
Edit: Look at Eng.Fouad's example to see how this is implemented.

Generate and store random numbers in set
Set<Integer> set = new HashSet<Integer>(100);
Random rand = new Random();
while (set.size() < 1000) {
set.add(rand.nextInt(100));
}
for (Integer integer : set) {
System.out.println(integer);
}

Related

Java Random Between Variables

I'm trying to randomize between these 3 variables (not range, but only between these 3 values) and store it into new variable.
int randomProductDiscount() {
int disc1 = 25;
int disc2 = 35;
int disc3 = 50;
int productDiscount = (random between disc1 or disc2 or disc3);
return productDiscount;
}
Any help would be appreciated.
Put them in an array and obtain random index:
static Random rand = new Random();
int randomProductDiscount()
{
int[] disc = {25,35,50};
return disc[rand.nextInt(disc.length)];
}
This can be used for any number of values you wish to choose randomly from.

Random Number generating in java without having any number of 0 in it

I have to generate 5 digit random number , without having any zeros in it. I have tried with below code, sometimes it works and sometimes it doesn't. Is there any better way to do this?
public Integer generateLastFiveSequenceNumbers()
{
Random ranndomNumber = new Random();
Random replaceNumber = new Random();
Integer fiveDigitRanndomNumber = 11111 + ranndomNumber.nextInt(99999);
Integer replaceZeroNumber = 1 + replaceNumber.nextInt(9);
String tempValidation = fiveDigitRanndomNumber.toString();
char[] ch = tempValidation.toCharArray();
for(int i = 0 ; i < ch.length-1 ;i++)
{
if(ch[i]=='0')
{
ch[i] = '1';
}
}
String newValue = new String(ch);
Integer finalNumber = Integer.parseInt(newValue);
return finalNumber;
}
While your intended method of replacing zero digits with additional random numbers is reasonably sound in theory, you are not using the replacement digits anywhere. Your final verification loops over all but the last index, which is the error that causes zeros to appear sometimes. Replacing all zeros with just ones defeats much of the randomness since ones are now twice as likely to appear as any other digit.
A simpler solution might be to concatenate five random digits that are guaranteed to be in the valid range to begin with. Since your return value is a number, you don't need to deal with strings at all:
public Integer generateLastFiveSequenceNumbers()
{
Random ranndomNumber = new Random();
int result = 0;
for(int i = 0; i < 5; i++) {
result = result * 10 + (randomNumber.nextInt(9) + 1);
}
return result;
}
Your idea above with an int stream:
public static int generateLastFiveSequenceNumbers( ) {
Random r = new Random();
return r.ints(11111, 99999+1)
.filter(i->!String.valueOf(i).contains("0"))
.limit(1).findFirst().getAsInt();
}
Combination of the above answers:
Integer rand = Integer.valueOf(
IntStream.rangeClosed(1,5) // repeat 5 times.
.map(x -> { return new Random().nextInt(9) + 1;} // Random between 1 and 9.
.boxed() // Convert to a stream of Integer objects.
.map(String::valueOf) // Convert from Integer to String.
.collect(Collectors.joining())); // Concat them all together.
System.out.println(rand);
public static void generateRandom(int howMany) {
int c = 0;
int multiplicator = 1;
Integer number = 0;
while (c < howMany) {
number += multiplicator * getRandom();
multiplicator = multiplicator * 10;
c++;
}
System.out.println(number);
}
public static Integer getRandom() {
Random rand = new Random();
return rand.nextInt(9)+1;
}
This solution uses a BiFunction (java 8 only).
BiFunction<Integer,Integer,Integer> customRandom = (min,max) -> {
int val = 0;
Random r = new Random();
do {
val = min + r.nextInt(max);
} while (String.valueOf(val).contains("0")); // skip randoms containing '0'
return val;
}
Usage:
System.out.println(customRandom.apply(10000,99999));

How to call if statements on arrays in java

import java.util.Random;
public class Console {
public static void main(String[] args) {
while (3>2) {
Random rand1 = new Random();
Random rand2 = new Random();
Random rand3 = new Random();
Random rand4 = new Random();
Random rand5 = new Random();
Random rand6 = new Random();
Random rand7 = new Random();
Random rand8 = new Random();
int onenum = rand1.nextInt(2);
int twonum = rand2.nextInt(2);
int threenum = rand3.nextInt(2);
int fournum = rand4.nextInt(2);
int fivenum = rand5.nextInt(2);
int sixnum = rand6.nextInt(2);
int sevennum = rand7.nextInt(2);
int eightnum = rand8.nextInt(2);
int binary[] = {onenum, twonum, threenum, fournum, fivenum, sixnum, sevennum, eightnum};
System.out.println(java.util.Arrays.toString(binary));
How can I check if, say the first number of the binary array is one?
Currently if I run, i get an output of like {1, 0, 1} ect
You can do it by using an index to access to an element in a specific position of an array:
if (someArray[position] == something)
In your case, to check the first element, it would be:
if (binary[0] == 1)
Note:
Indices in most programming languages start with 0 so the first element would be in the index 0 of the array. The second in the index 1. And so on.
Gosh i can reduce your code so much!! Analyse and see that this code does same as yours.
while (3>2) {
Random rand = new Random();
int[] binary = new int[8];
for(int i=0;i<8;i++)
binary[i] = rand.nextInt(2);
if(binary[0] == 1)
//if first number is 1
}
You can simply do:
if(binary[0] == 1) {
//do something
}
0 is the first element in array, since the fact of Arrays is a 0 based.
Side note: You don't have to declare a new object from Random to get a number, you can use the same object like:
Random rand = new Random();
int onenum = rand.nextInt(2);
int twonum = rand.nextInt(2);
int threenum = rand.nextInt(2);
// and so on
Just do this to check if first element equals to 1:
if (binary[0] == 1)
{
//do whatever here..
}
Other issues about your codes
I realized you use while (3>2). You can use while(true) if you want it to be an infinite loop.
You only need to create one random object to create multiple random numbers. Do it like this..
.
Random rnd = new Random();
oneNum = rnd.nextInt(2);
twoNum = rnd.nextInt(2);
threeNum = rnd.nextInt(2);
You can even do it this way (using an array to store the random numbers):
Random rnd = new Random();
int[] num = new int[8];
for (int x=0; x<num.length; x++)
num[x] = rnd.nextInt(2);

Using an int variable for list placements

I'm not sure if my wording is correct. I'm hoping it'll be more clear with this.
Integer[] Performed = new Integer[3];
public String dived(){
while (this.numberAttempts<3){
int n = this.numberAttempts;
int k = Dive.chosenRandomly();
this.Performed[n] = k ;
numberAttempts += 1;
}
return null;
}
I want the values of k(the random number) to be kept in a list so I know which numbers were chosen.
Is there a way for me to add values into the list in a while loop?
It works if I replace the n in [] with an integer<3.
Just use some list for example ArrayList and add random Integer to it.
List<Integer> Performed = new ArrayList<Integer>();
public String dived(){
while (this.numberAttempts<3){
int n = this.numberAttempts;
int k = Dive.chosenRandomly();
this.Performed.add(k) ;
numberAttempts += 1;
}
return null;
}

Java/Android Biased Number Generator

I have been set a task to create a Android app in which the user chooses four numbers (1-6), I then compare it against four randomly generated numbers and then tell them how many of there numbers were correct.
My problem is that whenever I generate any numbers the first three shown are always the same, except from the last number.
Random a1 = new Random();
random1 = new ArrayList<Integer>();
for (int index = 0; index < 6; index++)
{
random1.add(a1.nextInt(5)+ 1);
}
Random a2 = new Random();
random2 = new ArrayList<Integer>();
for (int index = 0; index < 6; index++)
{
random2.add(a2.nextInt(5)+ 1);
}
This is the code I use for the random number generation, each number uses the exact same code, which makes it even more confusing, if they were all the same I could understand that because it's the same code it generates the same number or something along those lines but the last one is always different, any help would always be appreciated.
Try not create two Random instances but reuse single instance instead. May be two Randoms with close seeds produces close output.
Check if below code works for you. Code taken from http://www.javapractices.com/topic/TopicAction.do?Id=62. Modified according to your requirements.
public final class RandomRange {
public static final void main(String... aArgs) {
int START = 1;
int END = 6;
Random random = new Random();
List<Integer> first = new ArrayList<Integer>();
List<Integer> second = new ArrayList<Integer>();
for (int idx = 1; idx <= END; ++idx) {
first.add(showRandomInteger(START, END, random));
second.add(showRandomInteger(START, END, random));
}
System.out.println(first);
System.out.println(second);
first.retainAll(second);//Find common
System.out.println(first);
}
private static int showRandomInteger(int aStart, int aEnd, Random aRandom) {
if (aStart > aEnd) {
throw new IllegalArgumentException("Start cannot exceed End.");
}
// get the range, casting to long to avoid overflow problems
long range = (long) aEnd - (long) aStart + 1;
// compute a fraction of the range, 0 <= frac < range
long fraction = (long) (range * aRandom.nextDouble());
int randomNumber = (int) (fraction + aStart);
return randomNumber;
}
}

Categories

Resources