I want to generate random number say between 1 to 100, but want to exclude ranges from 20 to 30 and 50-70.
3 Answers 3
Random random = new Random();
final int AMOUNT_OF_RANGES = 3;
int num;
int range;
range = random.nextInt(AMOUNT_OF_RANGES) + 1;
switch (range){
case 1 -> num = random.nextInt(1, 21);
case 2 -> num = random.nextInt(30, 51);
case 3 -> num = random.nextInt(70, 101);
}
I took a range [1,20] and [30, 50] and [70, 100] as an example but actually u can add as many as u want. Make sure to add extra one to max digit to include it.Usually it works like [1, 20), so keep it in mind. Syntax is
random.nextInt(startOfRange, endOfRange);
1 Comment
The ranges are not same so using a selector like r.nextInt(0,3)
to decide which range to use would be inbalanced, in favour of the short ranges over bigger 70-100.
Instead use one range and adjust with if statement something like (not near a PC to test):
Random r = new Random();
int x = r.nextInt(1,69);
if ( x >= 39)
return x + 32;
else if ( x >= 20)
return x + 11;
else return x;
This should handle 1..19, 31..49 and 71..100, but you may need to adjust if 30/70 are needed.
Comments
Just for fun you can create an Interface that returns an IntSupplier
to generate a random number in any number of ranges. This is related to my earlier comment where an array's cell with a random number is referenced. This is better in that the value is not generated until after the IntSupplier
is chosen and invoked.
First the interface contains a predefined Random instance and a static method which takes an array of ranges. The arrays of IntSuppliers
for each individual range is created using a stream. The supplier to use is indexed from 0 to the number of ranges
provided.`
interface RandomGenerator {
final Random r = new Random();
public static IntSupplier forRanges(int[][] v) {
IntSupplier[] sups = Arrays.stream(v)
.<IntSupplier>map(
range -> () -> r.nextInt(range[0], range[1]))
.toArray(IntSupplier[]::new);
return () -> sups[r.nextInt(0, sups.length)].getAsInt();
}
}
Generate a supplier and display some values. I am using extremely limited ranges to facilitate visual verification.
IntSupplier rnd = RandomGenerator.forRanges(
new int[][] { { 1, 3 }, { 31,33 }, { 91,93 } });
for (int i = 0; i < 10; i++) {
System.out.println(rnd.getAsInt());
}
prints something like the following:
31
1
91
1
2
32
31
2
2
31
At first glance, the statement return () -> sups[r.nextInt(0, sups.length)].getAsInt();
may appear confusing. What is happening is that the index to the supplier array sup
is called to get the appropriate IntSupplier
for the chosen range. Then that supplier's getAsInt
is called to get the random number. What is returned is yet another IntSupplier
which also has that number. It could look something like ()-> 2
. So when rnd.getAsInt
is called, it returns 2
.
This ensures that each invocation by rnd.getAsInt()
will return a random number from a random range.
Random r = new Random(); int v = new int [] {r.nextInt(1,20), r.nextInt(30,50), r.nextInt(70,100)}[r.nextInt(0,3)];
Note that ranges int java are specified and thus presumed to be inclusive to exclusive.