So I was looking to randomize the way certain methods are called, so that each one is only called once per instance and every single method is called.
So say one instance they are called in the order:
method2
method4
method3
method1
but in the next instance they are called in a different order:
method3
method2
method1
method4
The code that I have to randomize the order looks like this:
public void randomCalls(){
int[] order = new int[4];
for(int i=0; i<order.length; i++){
order[i]=nextNumber(order);
}
}
public int nextNumber(int[] array){
Random r = new Random();
int x = r.nextInt();
for(int i=0; i<array.length; i++){
if(arrayHasNumber(array,x)){
x = nextNumber(array);
}
}
return x;
}
public boolean arrayHasNumber(int[] array, int x){
for(int i=0;i<array.length;i++){
if(array[i]==x){
return true;
}
}
return false;
}
Based on #Aurand suggestion, you can have a switch that will call your methods and a List<Integer> that will contain the indexes of the methods you want to invoke, then shuffle the list elements using Collections.shuffle and calling the switch to call your methods. Code sample:
final int METHODS_QUANTITY = 4;
List<Integer> lstIndexes = new ArrayList<Integer>();
for(int i = 1; i <= METHODS_QUANTITY; i++) {
lstIndexes.add(i);
}
//you can change the condition for the number of times you want to execute it
while(true) {
Collections.shuffle(lstIndexes);
for(Integer index : lstIndexes) {
switch(index) {
case 1: method1(); break;
case 2: method2(); break;
case 3: method3(); break;
case 4: method4(); break;
}
}
}
Still, the question stands: why would you need this on real world application?
Something like
LinkedList methods
methods.add(1)
methods.add(2)
....
for(i=0; i<methods.size;i++)
r = random.next(methods.size)
switch(methods.get(r)) {
case 1: method1()
case 2: method2()
...
methods.remove(methods.get(r)
My tip would be to go for an ArrayList & thrown in all the method names during initialization.
Then get a random number using random(list.size()) and pop that element out from the ArrayList.
Use a switch case, and whatever method name has popped out, call that method.
Keep doing this, till the list becomes empty.
Possibly you must retain the states (orders in which the calls were made) in an internal variable or in an array (in case you want to have all of them). And then tune your call site to use this state variable.
Related
I am using a random number in a switch case. So have something like:
public void something {
Random myRand = new Random();
int number = myRand.nextInt(10 - 1) + 1;
switch(number)
case 1:
Do something and on completion go back and start running the something method again.
break:
case 1;
Do something and on completion go back and start running the something method again.
break;
Each case statement could be run through any number of times depending on input from user, some may not even be used.
What I would like is something inside the case statement saying :-
public void something (run);
Is what I am trying to do possible or is there a better way?
You can use do-while statement in this case with a condition to stop the execution.
Call your something method inside do while.
do {
something();
} while(condition);
This will call your method execute your switch case and again call your something method.
may i suggest you using interfaces?
what you are trying to implement is known as functional programming in which you pass functions as an argument to another functions
java supports functional programming in a way by using interfaces and has many built-in interfaces to ease-up the process
i recommend you to take a look at java.util.function package
now lets get on to your code
public void something(Supplier<Void> function) {
boolean condition = true; //use this boolean to control your loop
while (condition) {
Random myrand = new Random();
int number = myrand.nextInt(10 - 1) + 1;
switch (number) {
case 1:
function.get();
break;
case 2:
function.get();
break;
}
}
}
and you can call your "something" like this
public void Call() {
//if you want to declare the function only once
something(new Supplier<Void>() {
#Override
public Void get() {
System.out.println("the job is done!");
return null;
}
});
// if you already have a class implementing supplier
something(new MyFunction());
}
not that the Supplier interface is used because your function didn't have any inputs
you can also use Consumer, BiConsumer, Function, BiFunction .... for functions with inputs
The following code repeatedly calls the runSomeMethod() method for a random number of times.
Use a for loop:
public void something() {
Random myrand = new Random();
int number = myrand.nextInt(10 - 1) + 1;
for(int i=0 ; i<number ; i++) {
runSomeMethod();
}
}
concerned about your CASE syntax used
Solution goes as follows --> keep looping in a while loop
public void something {
boolean condition = true; // toggle this condition boolean to FALSE, when you want to break the loop
while(condition){
Random myrand = new Random();
int number = myrand.nextInt(10 - 1) + 1;
switch(number)
case 1;
Do something and on completion go back and start running the something method again.
break;
case 1;
Do something and on completion go back and start running the something method again.
break;
}
}
What I want to do: read strings from keyboard using Scanner until specific string is used to break the infinite loop. save them in an arrayList, then pass them into an array with its length beeing the number of the iteration of the loop
public class InputReader {
ArrayList<Integer> list = new ArrayList<>(0);
int arrayLength;
String readInput;
Scanner ir = new Scanner(System.in);
void readInput() {
for (int m=0; ;m++) {
readInput = ir.nextLine();
if ("q".equals(readInput)) {
//problem: arrayLength does not have the value of m outside the loop
arrayLength = m;
break;
}
System.out.println("arrayLength: "+arrayLength);
intInput = Integer.parseInt(readInput);
list.add(intInput);
}
}
int[] array = new int[arrayLength];
}
}
Inside the loop arrayLength works perfectly but outside the loop it has no value as I initialized it without value. Because of this,
System.out.println("array.length: "+array.length);
always returns 0 and the compiler returns this error:
java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
when I try to save integers inside the array.
1) How can I make the changes to the variable stay outside the loop?
2) Weird observation A:
int[] array = new int[list.size()];
returns the same error despite list.size() having the right value even outside the loop (checked by printing it).
And B: The code works if I create my array inside another method instead of inside the class and then use it in the method, but this way I cannot use it in my other classes despite using inheritance or parameters.
void giveOutput() {
int[] array = new int[list.size()];
public void giveOutput () {
System.out.println("list.size()"+list.size());
System.out.println("array.length:"+array.length);
for (int n=0; n<list.size(); n++) {
array[n] = list.get(n);
System.out.print("array["+n+"]:"+array[n]+" ");
}
}
}
this creates a working array but I cant hand it over to my Minsort extends InputReader subclass where it is sorted which leads to question number
3) How to use variables initialized in methods in other classes? This way my program could work too.
(I am a bloody beginner, started seriously working with java yesterday, my first succesful project was a Minsort-Algorithm I wrote from scratch so please have mercy. And thanks in advance.)
The array array is initialized when an object of the type InputReader is instantiated, not after the readInput() method is run.
In other words, array is always initialized when you use new InputReader(), not after the readInput() method is run. That means that the arrayLength variable has not yet been modified at the moment when array is created, so the default value for an int is used, which is 0.
Try this:
public static class InputReader {
ArrayList<Integer> list = new ArrayList<>(0);
int arrayLength;
String readInput;
Scanner ir = new Scanner(System.in);
int[] array;
void readInput() {
for (int m=0; ;m++) {
readInput = ir.nextLine();
if ("q".equals(readInput)) {
//problem: arrayLength does not have the value of m outside the loop
arrayLength = m;
break;
}
int intInput = Integer.parseInt(readInput);
list.add(intInput);
}
System.out.println("arrayLength: "+arrayLength);
array = new int[arrayLength];
}
}
Also, your System.out.println("arrayLength: "+arrayLength); always returned 0 because the arrayLength changes only when q is pressed.
To answer your third point: You could create a getter function in the class InputReader. For example:
public int[] getArray() {
return array;
}
As a side-note: It is very good practice to have your instance variables be declared with a private access modifier, and to then create public getter and setters. This is called Encapsulation, and is an OOP principle (my advice is that you google the OOP principles).
More info about getters and accessors here: Why use getters and setters/accessors?
First i add new Popotnik in List popotnik depending on how big it is, which is working fine - function prostaMesta. Then i want to go through list popotnik and set popotnik value depending on where it is in for, but value of i will always be 0 everytime it is being called. Also i have break there as i only want to set one popotnik at the time. How should i increment (i) while having some sort of break in there?
Also if(popotnik.get(i) == null){} is not being called, but values inside popotnik are null(s)
private List<Popotnik> popotnik = new ArrayList<Popotnik>();
public void prostaMesta(List<Popotnik> popotnik, int sedez){
stanovanje.setPostle(sedez);
for(int i=0; i<stanovanje.getPostle(); i++){
popotnik.add(new Popotnik());
}
System.out.println(popotnik);
}
public void dodajPotnika(List<Popotnik> popotnik, Popotnik popotnik2){
for(int i=0; i<popotnik.size(); i++){
if(popotnik.get(i) == null){
setPopotnik(popotnik, i);
popotnik.set(i, popotnik2);
break;
}
}
System.out.println(getPopotnik());
}
public void setPopotnik(List<Popotnik> popotnik, int i){
this.popotnik = popotnik;
}
public List<Popotnik> getPopotnik(){
return popotnik;
}
Main class:
List<Popotnik> alPopotnik = new ArrayList<Popotnik>();
if(x.equals("p")){ //inside of a loop when prostaMesta() is being called
potovanje.prostaMesta(alPopotnik, sedez);
}
`if(x.equals("d")){` //inside of a loop when dodajPotnika() is being called
System.out.println("Vnesi ime: ");
String ime = skener.next();
Popotnik popotnik = new Popotnik(ime);
potovanje.dodajPotnika(alPopotnik, popotnik);
}
The if(popotnik.get(i) == null) is never true because objects on the list are not null. You initialize them in the for loop in prostaMesta.
If you have some fields inside the Popotnik class then they are null, but object itself is not.
You would need to do something like popotnik.get(i).getName() == null.
Besides, if you only want to add a number at the end of popotnik's name then it isn't necessary to initialize a list with empty objects.
You could just add objects to list using a different constructor.
For example popotnik.add(new Popotnik("Popotnik"+(popotnik.size()+1))).
It's not pretty but I think initialization like this here is not necessary.
I want to know better way for coding in terms of memory management,
Method 1:
Obj temp;
public static Obj fun1() {
......
......
Obj temp = new Obj();
return temp;
}
Method2:
public static Obj fun1() {
........
.........
return new Obj;
}
which method will be good ? both method does the same work. but second method returns creating new Object, whereas first method create Object store it in variable and returns the variable.
Please consider that my function is going to have large number of such function returning Object of different class. and they will be called many many times during execution of Automated Test programme. So which one should I use and why ?
Use a singleton pattern . Create static object once if same instance can be used across
It will be like
static Object temp;
public Object getObjectInstance(){
if(temp==null){
temp = new Object();
}
return temp;
}
Both ways are ok, and have the same impact on the memory. The first one is used if you want to do something with the object inside the function before return it. The secone one assumes you don't want to do that.
To answer: There is very insignificant difference in 2 approaches you specified. As you are also aware that in both approaches a new object will be created, so that works well for you. Now your concern that in second approach a new variable will be used for store the object reference - but it is really insignificant because as soon as method will end, all the local variables created by the method will be removed from stack.
Concept:
Objects live in heap of area of the memory.
Variables live in the stack, and as soon as method finishes all local variables created by that method are removed from stack.
In nutshell: For your given you methods, hardly any difference in terms of memory management.
There is an actual difference within bytecode. Let's take the following class.
public class Test {
public static void main(String... args) {
final int LIMIT = 10_000_000;
final int RUNS = 10;
for (int run = 0; run < RUNS; ++run) {
Test[] t = new Test[LIMIT];
long start = System.nanoTime();
for (int i = 0; i < LIMIT; ++i) {
t[i] = fun1();
}
System.out.println( "fun1: "
+ ((System.nanoTime() - start) / 1_000_000_000d)
+ "s");
t = new Test[LIMIT];
start = System.nanoTime();
for (int i = 0; i < LIMIT; ++i) {
t[i] = fun2();
}
System.out.println( "fun2: "
+ ((System.nanoTime() - start) / 1_000_000_000d)
+ "s");
}
}
public static Test fun1() {
return (new Test());
}
public static Test fun2() {
Test t = new Test();
return (t);
}
}
When you look at the bytecode for the methods fun1() and fun2(), they will look like this:
public static Test fun1();
Code:
0: new #1 // class Test
3: dup
4: invokespecial #20 // Method "<init>":()V
7: areturn
public static Test fun2();
Code:
0: new #1 // class Test
3: dup
4: invokespecial #20 // Method "<init>":()V
7: astore_0 // those lines are
8: aload_0 // unique to fun2()
9: areturn
As you execute this code, you may notice that the execution times get faster and faster. I think this is due to the JIT-compiler. At the end, however, there is hardly a difference performancewise.
Both methods are almost similar. In method 1, if you are returning immediately after assigning the object to reference variable, then there is no point in assigning it to refence variable. In which case method 2 should be opted for.
Obj temp = new Obj(); //if you are not doing anything with temp but just returning then go with method 2
return temp;
However if you have to mutate the object ot do some operations, then method1 should be good as you will be getting the reference to that object in 'temp'
Obj temp = new Obj(); //if temp is used before return, then go with method 1
return temp;
Note: Only the object takes the memory on heap NOT the reference variable.
Well I discussed with expert, have found that using following method will create a memory allocation in stack every time we create new object.
method1 () {
return new ClassObj();
}
method2 () {
return new ClassObj();
}
method3 () {
return new ClassObj();
}
method4 () {
return new ClassObj();
}
method5 () {
return new ClassObj();
}
and this stack memory go on allocating. If we are calling this function many times during run ( as it happens generally in running automated script) same function called many times again and again, this stack accumulation go on increasing.
So to avoid this use some temp object that will catch the object returned by method. So instead of allocation memory in stack, this will delete previous memory data of temp object and replace it with new one.
ClassObj temp;
method1 () {
temp = new ClassObj();
return temp;
}
method2 () {
temp = new ClassObj();
return temp;
}
method3 () {
temp = new ClassObj();
return temp;
}
method4 () {
temp = new ClassObj();
return temp;
}
method5 () {
temp = new ClassObj();
return temp;
}
So, I know you can't use a variable in the case statement. I am hoping someone can point me to code that would be fairly efficient as a replacement. (I could do a bunch of ifs, for example).
The situation is that I have an array of object data, and I want to iterate through that array. The position in the array is given by a name as shown below (the int...ordinal statements). Basically I have to assign generate 'result' objects for certain members of the array (if they are discrete data such as C_VENT_RATE). The only way I can see this done easily is do a bunch of ifs such as if (i.equals(pr_int)).
ArrayList<String[]> rawEKGs = ekgFile.getForMrno( docInfo.getMedicalRecordNumber() );
for (String[] parts : rawEKGs) {
for (int i=0; i< parts.length; i++ )
{
Result result = docInfo.getResult();
boolean process = true;
final int vent_rate = UncEKG.COL_NAMES.C_VENT_RATE.ordinal();
int art_rate = UncEKG.COL_NAMES.C_ART_RATE.ordinal();
int pr_int = UncEKG.COL_NAMES.C_PR_INTERVAL.ordinal();
int qrs_dur = UncEKG.COL_NAMES.C_QRS_DURATION.ordinal();
int qt_qtc = UncEKG.COL_NAMES.C_QT_QTC.ordinal();
int prt = UncEKG.COL_NAMES.C_PRT_AXES.ordinal();
switch(i) {
case : // something
break;
default: process = false;
}
Since you already have an enum, you can try the Command pattern using an EnumMap mapping your enum to a Command.
Each Command instance will be the same logic as one of your case statements.
EnumMap<UncEKG.COL_NAMES, Command> map = ...
//values is in ordinal order
//pulled out for performance reasons
UncEKG.COL_NAMES[] names = UncEKG.COL_NAMES.values();
for (String[] parts : rawEKGs) {
for (int i=0; i< parts.length; i++ ){
map.get(names[i]).execute();
}
}
I think the right way is to put the logic in the enum. So you would add a static method to the enum class to get the right column based on the int, and then you can switch based on the enum, or perhaps do something else, or even better have a method on the enum which says if that column is processed or not (although that may not be appropriate if the enum is more general purpose).
Quick and dirty would look like this, though:
ArrayList<String[]> rawEKGs = ekgFile.getForMrno( docInfo.getMedicalRecordNumber() );
UncEKG.COL_NAMES[] values = UncEKG.COL_NAMES.values();
for (String[] parts : rawEKGs) {
for (int i=0; i< parts.length; i++ )
{
Result result = docInfo.getResult();
boolean process = true;
switch (values[i]) {
case UncEKG.COL_NAMES.C_VENT_RATE:
break;
default: process = false;
}
}
}
Do like this way
switch(i) {
case 0: // something
break;
case 1: // something
break;
case 2: // something
break;
.
.
.
.
default: process = false;
}
If the object contains an enum (UncEKG) as a variable, why not just use the switch on the enum
switch (theEnum) {
case UncEKG.COL_NAMES.C_VENT_RATE:
//something
break;
case UncEKG.COL_NAMES.C_PR_INTERVAL:
//something else
break;
default: process = false
}
Enum info