Im a newcomer :)
However, my program has a table and a RandomGen should get the highest random int by getRowCount -> checkvar1.
Now, the main class gets checkvar1 and sends it to setVariable(), then I want to exchange this checkvar1 with randomGen to limit the maximum generated integer.
So this of course doesn't work because the parameters in randomGen() aren't set and I cannot set them, because then the exchange to the onActionPerformed() method in my main class doesn't work anymore.
public final class RandomGen
{
// EXCHANGE OF CHECKVAR1 FOR RANDOM GEN
public static void setVariable(int checkvar1)
{
System.out.print(checkvar1);
}
// RANDOM GENERATOR
public static int randomGen()
{
Random rand = new Random();
int var1 = rand.nextInt(checkvar1) + 1;
return var1;
}
}
Here my main class:
public void onActionPerformed(java.awt.event.ActionEvent evt) {
//NUMBER OF LAST ROW
int checkvar1 = (Integer)jTable1.getRowCount();
//->EXCHANGE WITH setVariable()
RandomGen.setVariable(checkvar1);
if (checkvar1 >= 3) {
int recogvar1 = checkvar1 - 1;
Object checkobj1 = jTable1.getModel().getValueAt(recogvar1, 0);
if (checkobj1 == null){
//...
}
else {
int var1 = RandomGen.variable();
String result = var1 + "";
jTextField1.setText(result);
//System.out.print(result);
}
}
else {
String rule2 = "At least " + 3 + " rows should be filled";
jTextField1.setText(rule2);
}
You are doing nothing with your setVariable in your class RandomGen. So You only need to change this.
// RANDOM GENERATOR
public static int randomGen(int checkvar1)
{
Random rand = new Random();
int var1 = rand.nextInt(checkvar1) + 1;
return var1;
}
And in your main Method try this.
//NUMBER OF LAST ROW
int checkvar1 = (Integer)jTable1.getRowCount();
//->EXCHANGE WITH randomGenerator
checkvar1 = RandomGen.randomGen(checkvar1);
Related
I want to produce unique values of Movie Object via Random. I wrote a code snippet but I'm not sure all values cannot be unique by using Random().
How can I do this process to produce all of these unique values?
Here is my code snippets shown below.
private static ArrayList<Movie> addMovies(ArrayList<Movie> movieList) {
for(int i=0;i<20;i++) {
Movie movie = new Movie();
movie.setId(defineMovieId());
movie.setTitle(defineMovieName(15));
movieList.add(movie);
}
return movieList;
}
public static String defineMovieName(int n) {
// chose a Character random from this String
String AlphaNumericString = "ABCÇDEFGHIİJKLMNOÖPQRSŞTUÜVWXYZ"
+ "abcçdefghıijklmnoöpqrsştuüvxyz";
StringBuilder sb = new StringBuilder(n);
for (int i = 0; i < n; i++) {
int index
= (int)(AlphaNumericString.length()
* Math.random());
sb.append(AlphaNumericString
.charAt(index));
}
return sb.toString();
}
public static long defineMovieId() {
int max = 1000;
int min = 1;
int range = max - min + 1;
int res = (int) ( Math.random()*range) + min;
return res;
}
The methods which you have defined do not guarantee random IDs or random names. For guaranteed unique values, you can do the following:
For unique ID: create a static variable of AtomicLong type and use getAndIncrement()
For unique names: use UUID.randomUUID()
Demo:
import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;
public class Main {
static final long INITIAL_VALUE = 1000000;
static AtomicLong atomicLong = new AtomicLong(INITIAL_VALUE);
public static void main(String[] args) {
// Tests
System.out.println("10 random IDs:");
for (int i = 1; i <= 10; i++) {
System.out.print(defineMovieId() + " ");
}
System.out.println();
System.out.println("10 random movie names:");
for (int i = 1; i <= 10; i++) {
System.out.print(defineMovieName() + " ");
}
}
public static long defineMovieId() {
return atomicLong.getAndIncrement();
}
public static String defineMovieName() {
return UUID.randomUUID().toString().replace("-", "");
}
}
Output:
10 random IDs:
1000000 1000001 1000002 1000003 1000004 1000005 1000006 1000007 1000008 1000009
10 random movie names:
0c77d209fb624415af7100c3184b35a6 1262e50b680f4a738a607ff757f2b510 7b93c73d93b34db88fc99d1096c1ce84 cbb9c6c90fb8489dbd9c52d4ebdc2ca3 9ba1d409b32b4c55a7562d714aadc220 ec40b647f33a4fc6becc8c5741eb8bf7 c1fbb7bb77d1417c86c2064039f62dec 82b52fdae1d24602b5ee9becd73ba3ce 2d82d481282b4684b55c168e9d216f36 27b02bf63b054d32a0e43992a5fcb124
Random is not generate a series of unique numbers, just if get lucky.
Better use a static int field for id and increase it each time you need a new id.
//classes names are obvious fake since there are not any random involved, just an example
public class TestRandom {
static int id=0;
public static void main(String[] args)
{
TestRandom tr = new TestRandom();
RandomIdObj ro1 = tr.new RandomIdObj(tr.getNextId(),"obj_1");
RandomIdObj ro2 = tr.new RandomIdObj(tr.getNextId(),"obj_2");
System.out.println(ro1);
System.out.println(ro2);
}
public int getNextId()
{
return ++id;
}
class RandomIdObj
{
int id;
String name;
RandomIdObj(int id,String name)
{
this.id =id;
this.name = name;
}
public String toString()
{
return this.id+":"+this.name;
}
}
}
Output:
[unique_id,obj_name]
1:obj_1
2:obj_2
I have a method that returns a random value.
public int newRandom() {
Random random = new Random();
int o = random.nextInt(9 - 0 + 1) + 0;
return o;
}
After I generate that value I'm currently setting a variable inside another method to the result of this function, what I want to do is have another class know the same result that variable has, what I mean is both having the same random number, I for some reason can't figure this out on my own. What would be the best way of achieving this?
Do you mean something like that?
import java.util.Random;
public class A
{
public static Random random = new Random();
}
public class B
{
public int getRandomInt()
{
return A.random.nextInt();
}
}
Create a Base class with a public static variable and when you inherit these new classes from the Base class and create new instances they share this same variable:
import java.util.Random;
class Base_class {
public static int o;
public Base_class() {
}
public int newRandom() {
Random random = new Random();
o = random.nextInt(9 - 0 + 1) + 0;
return o;
}
public int get_randn() {
return o;
}
}
class Derived_class1 extends Base_class {
public Derived_class1() {
}
}
class Derived_class2 extends Base_class {
public Derived_class2() {
}
}
class Main{
public static void main(String [] args){
Derived_class1 obj1 = new Derived_class1();
Derived_class2 obj2 = new Derived_class2();
obj1.newRandom();
System.out.println(obj1.get_randn());
System.out.println(obj2.get_randn());
}
}
Consider using composition where multiple objects (could be different classes) share the same instance of a class which provides the random values. For example, given this class to keep track of random values:
private class RandomProvider {
private final Random random = new Random();
private int currentValue;
private int newRandom() {
currentValue = random.nextInt(10);
return currentValue;
}
private int getCurrentValue() {
return currentValue;
}
}
and another class (or classes) which use a RandomProvider:
private class A {
private final RandomProvider randomProvider;
private A(RandomProvider randomProvider) {
this.randomProvider = randomProvider;
}
private int getCurrentRandomValue() {
return randomProvider.getCurrentValue();
}
}
So then a couple instances of A (or some other class) can use the same instance of RandomProvider:
RandomProvider randomProvider = new RandomProvider();
System.out.println("new random value is " + randomProvider.newRandom());
A a1 = new A(randomProvider);
System.out.println("A1 sees current random value as " + a1.getCurrentRandomValue());
A a2 = new A(randomProvider);
System.out.println("A2 sees current random value as " + a2.getCurrentRandomValue());
randomProvider.newRandom();
System.out.println("A1 sees current random value as " + a1.getCurrentRandomValue());
System.out.println("A2 sees current random value as " + a2.getCurrentRandomValue());
Sample output:
new random value is 9
A1 sees current random value as 9
A2 sees current random value as 9
A1 sees current random value as 3
A2 sees current random value as 3
I have tested the random number generator and it works fine outside of the app. It's a fairly standard piece of code. I created getters and setters, and NetBeans does not complain about anything being passed to the application, but what should be a random number is a "0". I would like to understand more about getters and setters and classes. I may have designated something incorrectly.
//This is the class code
public class RandomGen {
int minSeed = 100;
int maxSeed = 999;
int num;
public static void RandomNum(int minSeed, int maxSeed) {
Random rand = new Random();
int num = rand.nextInt(maxSeed - minSeed) + 1;
}
public void setMin(int minSeed) {
this.minSeed = minSeed;
}
public void setMax(int maxSeed) {
this.maxSeed = maxSeed;
}
public int getNum() {
return num;
}
}
This is the code within main in my application
RandomGen rnumber = new RandomGen();
int rnum = rnumber.getNum();
int bigSeed = rnumber.maxSeed;
int smallSeed = rnumber.minSeed;
System.out.println("Random Number = " + rnum);
System.out.println("MaxSeed = " + bigSeed);
System.out.println("MinSeed = " + smallSeed);
This is the printed return
Random Number = 0
MaxSeed = 999
MinSeed = 100
You have created a local variable so use the global as
num = rand.nextInt(maxSeed - minSeed) + 1;
As per your code , you need to call that static method to initialize num as well so
RandomGen rnumber = new RandomGen();
RandomGen.RandomNum(rnumber.minSeed, rnumber.maxSeed);
//^^^^^^^^^^^^^^^^^^^^^
int rnum = rnumber.getNum();
int bigSeed = rnumber.maxSeed;
int smallSeed = rnumber.minSeed;
Note: constructors cannot be static, can't have any return type
static int num; // global to class, different from the `num` inside RandomNum
public static void RandomNum(int minSeed, int maxSeed)
{
Random rand = new Random();
// local variable
// changes here, can only be seen inside RandomNum method
//int num = rand.nextInt(maxSeed - minSeed) + 1;
num = rand.nextInt(maxSeed - minSeed) + 1;
}
first
static int num; // must also be static
second
public static void RandomNum(int minSeed, int maxSeed)
{
Random rand = new Random();
num = rand.nextInt(maxSeed - minSeed) + 1; // remove the declaration you try to make it local variable
}
This is incorrect.
Try this:
import java.util.Random;
public class RandomGen {
private Random random;
private int minRange;
private int maxRange;
public static void main(String[] args) {
int minRange = (args.length > 0) ? Integer.parseInt(args[0]) : 100;
int maxRange = (args.length > 1) ? Integer.parseInt(args[1]) : 200;
int numValues = (args.length > 2) ? Integer.parseInt(args[2]) : 10;
RandomGen randomGen = new RandomGen(minRange, maxRange);
for (int i = 0; i < numValues; ++i) {
System.out.println(randomGen.getNextIntInRange());
}
}
public RandomGen(int minRange, int maxRange) {
this(minRange, maxRange, null);
}
public RandomGen(int minRange, int maxRange, Long seed) {
this.minRange = minRange;
this.maxRange = maxRange;
this.random = (seed == null) ? new Random() : new Random(seed);
}
public int getNextIntInRange() {
return this.minRange + this.random.nextInt(this.maxRange-this.minRange)+1;
}
}
Framework: Java
public static List<Integer> buttonIdList = new ArrayList();
public void myMainMethod() {
for(Integer i = 0; i < 11; i++) {
int randomButtonId = getUniqueIdNumber();
}
}
private static Integer getUniqueIdNumber() {
Random ran = new Random();
int randomButtonId = ran.nextInt(20) + 1;
if(buttonIdList.contains(randomButtonId)) {
getUniqueIdNumber();
} else {
buttonIdList.add(randomButtonId);
}
return randomButtonId;
}
When the code encounters a duplicate, it calls itself (recursively) and in the second try if the number is unique the return statement returns it to the myMainMethod or to getUniqueIdNUmber?
Where should the return statement be placed?
You should return the result of the recursive call:
private static Integer getUniqueIdNumber() {
Random ran = new Random();
int randomButtonId = ran.nextInt(20) + 1;
if(buttonIdList.contains(randomButtonId)) {
return getUniqueIdNumber();
} else {
buttonIdList.add(randomButtonId);
}
return randomButtonId;
}
P.S., it would be better to make Random ran a static variable instead of creating a new Random instance in each recursive call.
private static Random ran = new Random();
private static Integer getUniqueIdNumber() {
int randomButtonId = ran.nextInt(20) + 1;
if(buttonIdList.contains(randomButtonId)) {
return getUniqueIdNumber();
} else {
buttonIdList.add(randomButtonId);
return randomButtonId;
}
}
And you might consider changing buttonIdList to a HashSet (or LinkedHashSet if you care about insertion order) in order to make the search for existing number more efficient.
Final(?) edit:
Leonardo Pina's solution looks like what I needed. Thank you all for your input! My code is now:
public final class Roll {
private static final Random r1 = new Random();
private final int r = level();
private static final int level() {
int s = 1, e = 100;
int r = r1.nextInt((e - s) + 1) + s;
return r;
}
public int itemType() {
boolean b = r1.nextBoolean();
int a = ((b) ? 1 : 2);
return a;
}
public int getR() {
return r;
}
}
And the implementation in the other class:
public class Damage {
Roll r;
Damage(Roll r) {
this.r = r;
}
public int damageOut() {
int a = r.getR(); //roll value
return a * 2; //test math on r
}
}
Edit:
Thank you for the responses. However, it seems my use of this method was not clear. Apologies! This is what I need:
Call Roll class, get e.g. "12"
OtherClass1 receives "12" from Roll via getter
OtherClass2 also receives "12" from Roll via getter
Call Roll class again, get a new random number, e.g. "48"
OtherClass1 receives "48" from Roll via getter
OtherClass2 also receives "48" from Roll via getter
Using the solutions provided, Roll creates a single random number and never creates a new one again. I need Roll to create random numbers on demand, and then share that random number with other classes. I do not want it to only generate one number and then stop. I hope this makes sense. Thank you for the responses so far!
I have searched for and read the other threads of a similar topic (including this one, which is how I tried to solve my problem), but the methods I have tried have failed. I need to create a single random value and then use that same value across multiple classes.
My random class:
public final class Roll {
private static final Random r1 = new Random();
private final int r = level();
private static final int level() {
int s = 1, e = 100;
int r = r1.nextInt((e - s) + 1) + s;
return r;
}
public int itemType() {
boolean b = r1.nextBoolean();
int a = ((b) ? 1 : 2);
return a;
}
public int getR() {
return r;
}
}
And a class where I call for the static value from the random class:
public class OtherClass{
Roll roll = new Roll();
int r = roll.getR();
public int getR() {
return r;
}
}
When I call the getter from OtherClass, the value is different than the getter from Roll. I would expect them to be the same value.
I call the values for testing like so:
Roll roll = new Roll();
int r = roll.getR();
OtherClass other = new OtherClass();
int o = other.getR();
Any guidance would be greatly appreciated. Have a good day.
When you create a new instance of OtherClass you also create a new instance of Roll, therefore, the rolls are different.
You need to make sure you are getting the value R from the same object Roll.
This could be achieved by using a singleton pattern for the Roll class, or you could specify the Roll object you want to use to get values, this way you could have several rolls for different purposes. i.e.
Edit:
Answering your edit: to get a new number, you should update the value of r in the Roll class whenever you generate a new value, for example, instead of returning a value, the level() method could update the r variable:
public final class Roll {
private static final Random r1 = new Random();
// We now attribute a value to r uppon construction
private final int r;
public Roll() {
level();
}
// Whenever level() is called the value of r is updated
private static final int level() {
int s = 1, e = 100;
int r = r1.nextInt((e - s) + 1) + s;
this.r = r;
}
public int itemType() {
boolean b = r1.nextBoolean();
int a = ((b) ? 1 : 2);
return a;
}
public int getR() {
return r;
}
}
class Game {
public static void main(String[] args) {
// Create the Roll obj
Roll myRoll = new Roll();
// Initialize the other objs with myRoll
Board board = new Board(myRoll);
Player player = new Player(myRoll);
// Do your comparison
int b = board.getRoll();
int p = player.getRoll();
// EDIT: get a new value
myRoll.level();
// Do your comparison once more
b = board.getRoll();
p = player.getRoll();
}
class Board {
Roll r;
Board(Roll roll) {
this.r = roll;
}
public int getRoll() {
return r.getR();
}
}
class Player {
Roll r;
Player(Roll roll) {
this.r = roll;
}
public int getRoll() {
return r.getR();
}
}
}
Probably the simplest way to make it work would be to field r in class Roll as static, so that the Roll class looks like this:
ublic final class Roll {
private static final Random r1 = new Random();
private static final int r = level();
private static final int level() {
int s = 1, e = 100;
int r = r1.nextInt((e - s) + 1) + s;
return r;
}
public int itemType() {
boolean b = r1.nextBoolean();
int a = ((b) ? 1 : 2);
return a;
}
public int getR() {
return r;
}
}
Or second approach would be to make Roll class a singleton.
Edit:
Since you have changed the intent of the question, and from what I understand you should look into Observer design pattern. It may be helpful for your case.
As someone said in the comments, you should follow the singleton design pattern, meaning that your variable r should be unique across all Roll class instances. To do this, your code will have to look something like this:
public class RandomTest {
public static void main(String[] args) {
Roll roll = new Roll();
int r = roll.getR();
OtherClass other = new OtherClass();
int o = other.getR();
}
}
class Roll {
private static Random r1 = new Random();
private static int r = level();
private static final int level() {
int s = 1, e = 100;
int r = r1.nextInt((e - s) + 1) + s;
return r;
}
public int itemType() {
boolean b = r1.nextBoolean();
int a = ((b) ? 1 : 2);
return a;
}
public int getR() {
return r;
}
}
class OtherClass{
Roll roll = new Roll();
int r = roll.getR();
public int getR() {
return r;
}
}
How about sharing the Roll instance?
Roll roll = new Roll();
// roll.roll(); // Unclear how you "refresh" the data
int r = roll.getR();
OtherClass other = new OtherClass(roll);
int o = other.getR();
assert(o == r);
class OtherClass {
private final Roll roll;
public OtherClass(Roll roll) {
this.roll = roll;
}
public int getR() {
return roll.getR();
}
}
Tip: I think a Dice class with a roll() method makes more sense.