switch case statements and run method from inside - java

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;
}
}

Related

How to add ItemListeners dynamically?

I'm writing a program to calculate GPA. It consists of several panels. The first panel
tells the user to specify the number of courses so that Comboboxes (gradeCombo),(hourCombo) and Textfields will be added dynamically to the second panel . Everything is fine to this point but the problem is with the listeners. In early stages, I registered the event listeners for these comboboxes individually for every element in the array and it resulted in 900 lines of codes, but it worked fine and all my results were correct. To enhance my code I'm trying to write a for loop for registering the events for the comboboxes and so far I couldn't succeed.
I tried to write the handling code as anonymous inner class and as separate inner class, Here is my last try:
for(i = 0; i<courseN;i++)
{
hourCombo[i].addItemListener(new HoursHandler());
gradeCombo[i].addItemListener(new GradeHandler());
}
public class HoursHandler implements ItemListener
{
public void itemStateChanged(ItemEvent event)
{
if(event.getStateChange()==ItemEvent.SELECTED)
{
String hour;
hour = (String) hourCombo[i].getSelectedItem();
currentHour[i]=Integer.parseInt(hour);
aquiredHours=aquiredHours+currentHour[i] prevHour[i];
prevHour[i]=currentHour[i];
}
}
}
public class GradeHandler implements ItemListener
{
public void itemStateChanged(ItemEvent event)
{
if(event.getStateChange()==ItemEvent.SELECTED)
{
String grade;
grade=(String) gradeCombo[i].getSelectedItem();
switch(grade)
{
case "A+":
currentPoint[i]=5*currentHour[i];
break;
case "A":
currentPoint[i]= 4.75 * currentHour[i];
break;
case "B+":
currentPoint[i]= 4.5 * currentHour[i];
break;
case "B":
currentPoint[i]= 4 * currentHour[i];
break;
case "C+":
currentPoint[i]= 3.5 * currentHour[i];
break;
case "C":
currentPoint[i]= 3 * currentHour[i];
break;
case "D+":
currentPoint[i]= 2.5 * currentHour[i];
break;
case "D":
currentPoint[i]= 2 * currentHour[i];
break;
case "F":
currentPoint[i]= 1 * currentHour[i];
break;
}
aquiredPoints=aquiredPoints+currentPoint[i]-prevPoint[i];
prevPoint[i]=currentPoint[i];
}
}
}
I get a NullPointerException for this statement:
hour = (String) hourCombo[i].getSelectedItem();
and everything goes wrong, none of my variables is updated and I cannot calculate the GPA..
It's hard to tell from the posted code what is wrong there. However, I assume that i is declared as an instance variable. In this case, the loop for(i = 0; i<courseN;i++) will change the value of this instance variable. Afterwards, all the listeners will internally use i with the last value that it received in the for-loop.
To circumvent this, you can declare an instance variable for each listener instance. So you can change your listener classes like this:
public class HoursHandler implements ItemListener
{
private final int index;
HoursHandler(int index)
{
this.index = index;
}
#Override
public void itemStateChanged(ItemEvent event)
{
// Use the "index" here:
String hour = (String) hourCombo[index].getSelectedItem();
currentHour[index]=Integer.parseInt(hour);
...
}
}
(similarly, introduce such an index for the GradeHandler).
Then, when you create the listeners, you can pass to each instance the index that it refers to:
// Note: "i" is declared here, and should NO longer
// be an instance variable!
for(int i = 0; i<courseN;i++)
{
hourCombo[i].addItemListener(new HoursHandler(i)); // Use "i" as "index"
gradeCombo[i].addItemListener(new GradeHandler(i)); // Use "i" as "index"
}
I assume that there might be some more elegant solutions, but this is one possible solution, solely based on the code that you provided.
It appears that i is a member field in your outer class. When your listener is executed, and your listener
hour = (String) hourCombo[i].getSelectedItem();
this statement will use whatever value i happens to be in this outer class. And after you execute your for loop, i will probably be equal to courseN, unless there's something else changing it somewhere else. In any case, it doesn't use the value that i held when you set up the listener, because you did nothing to tell it to use that value.
A simple way to fix this is to construct your listeners by giving it the index you want them to use:
public class HoursHandler implements ItemListener
{
private final int index;
public HoursHandler(int index) {
this.index = index;
}
public void itemStateChanged(ItemEvent event)
{
if(event.getStateChange()==ItemEvent.SELECTED)
{
String hour;
hour = (String) hourCombo[index].getSelectedItem();
and use index instead of i everywhere in the listener. When you construct the listener, it will store the index you want, and then the code will use that instead of the current value of i. Similarly for GradeHandler. Then
for(i = 0; i<courseN;i++)
{
hourCombo[i].addItemListener(new HoursHandler(i));
gradeCombo[i].addItemListener(new GradeHandler(i));
}
Note that the index you want the listeners to use is now passed as a parameter to the listeners' constructors.
EDITED to use final on the index member--plagiarized from Marco13's good idea.

Unreachable Statement with Break

So I had a previous question but realized I posted the wrong offending code. I've marked the offending statements below.
What I am trying to do is set the precedence for each of the operators with that switch statement.
Maybe someone could point me in the right direction.
Just as a note, I AM running JAVA 7 so String Switch will work.
Code
opType.java
import java.io.*;
public final class opType {
public static opType ADD = new opType( "Add" );
public static opType SUB = new opType( "Sub" );
public static opType MULT = new opType( "Mult" );
public static opType DIV = new opType( "Div" );
public static opType MOD = new opType( "Mod" );
public static opType LPAR = new opType( "LParen" );
public static opType RPAR = new opType( "RParen" );
protected String name;
private opType( String n )
{
name = n;
}
public String getName()
{
return name;
}
Operator.java
public class Operator extends Token {
protected opType val;
public boolean isOperator() { return true; }
public boolean isOperand() { return false; }
protected int getPrec()
{
switch(val.getName())
{
case "LParen":
{
return 0;
break; //unreachable
}
case "RParen":
{
return 0;
break; //unreachable
}
case "Mult":
{
return 1;
break; //unreachable
}
case "Div":
{
return 1;
break; //unreachable
}
case "Mod":
{
return 1;
break; //unreachable
}
case "Add":
{
return 2;
break; //unreachable
}
case "Sub":
{
return 2;
break; //unreachable
}
}
return 0;
}
public static int compare( Operator a, Operator b )
{
if( a.getPrec() == b.getPrec() )
return 0;
else if( a.getPrec() < b.getPrec() )
return -1;
else
return 1;
}
public opType getVal() { return val; }
public Operator( opType v ) { val = v; }
}
If you put a return, then the function returns before the break is executed and therefore the break will never be reached.
Instead you could use a variable that you set to a desired value and after the switch return that. Or just get rid of the break statements.
you already have return which will make the break unreachable
The reason that the code is unreachable is due to the return behaving like a break in that context - they both complete abruptly.
If a statement completes abruptly, then execution at that line is immediately returned to its appropriate context; if it's a break, it'll attempt to either exit the switch or return to its associated label if one exists; if it's a return, it will return to its caller, with or without a value.
This is why the code is unreachable: the line of code after the return can not be reached.
To really understand what that means or entails, we have to look at the Java Language Specification, specifically 14.1:
Every statement has a normal mode of execution in which certain
computational steps are carried out. The following sections describe
the normal mode of execution for each kind of statement.
If all the steps are carried out as described, with no indication of
abrupt completion, the statement is said to complete normally.
However, certain events may prevent a statement from completing
normally:
The break (§14.15), continue (§14.16), and return (§14.17) statements
cause a transfer of control that may prevent normal completion of
statements that contain them.
Evaluation of certain expressions may throw exceptions from the Java
Virtual Machine (§15.6). An explicit throw (§14.18) statement also
results in an exception. An exception causes a transfer of control
that may prevent normal completion of statements.
If such an event occurs, then execution of one or more statements may
be terminated before all steps of their normal mode of execution have
completed; such statements are said to complete abruptly.
An abrupt completion always has an associated reason, which is one of
the following:
A break with no label
A break with a given label
A continue with no label
A continue with a given label
A return with no value
A return with a given value
A throw with a given value, including exceptions thrown by the Java
Virtual Machine
The terms "complete normally" and "complete abruptly" also apply to
the evaluation of expressions (§15.6). The only reason an expression
can complete abruptly is that an exception is thrown, because of
either a throw with a given value (§14.18) or a run-time exception or
error (§11, §15.6).
If a statement evaluates an expression, abrupt completion of the
expression always causes the immediate abrupt completion of the
statement, with the same reason. All succeeding steps in the normal
mode of execution are not performed.
Unless otherwise specified in this chapter, abrupt completion of a
substatement causes the immediate abrupt completion of the statement
itself, with the same reason, and all succeeding steps in the normal
mode of execution of the statement are not performed.
Unless otherwise specified, a statement completes normally if all
expressions it evaluates and all substatements it executes complete
normally.
The return statement effectively exits the method immediately. Since you've placed return statements inside the switch block for each case, whichever case is matched will, according to your code, return whatever value is indicated immediately. The break therefore cannot be executed, hence the error. You have two options:
1- Set a value, and return at the end of the method:
protected int getPrec(){
int prec = 0;
switch(val.getName()) {
case "LParen":
prec = 0;
break;
case "RParen":
prec = 0;
break;
case "Mult":
prec = 1;
break;
case "Div":
prec = 1;
break;
case "Mod":
prec = 1;
break;
case "Add":
prec = 2;
break;
case "Sub":
prec = 2;
break;
default:
prec = 0;
break; // technically unnecessary since we're at the end already but adding for completeness.
}
return prec;
}
2- Ditch the break; statements and keep the return statements as you've written them.
Personally I would prefer the first option as its cleaner and more readable to me. Plus it makes it easier to expand whatever actions need to be done in one or more cases if need be in the future.
By the way, watch your naming convention. You presently have:
public final class opType // bad naming
Since this is a class, the Java standard is to capitalize the first letter of the class. So it should be:
public final class OpType // good naming
Here you can comment the line return super.onOptionsItemSelected(item)
after commenting this line the code will run.
This Works for me
public boolean onOptionsItemSelected(MenuItem item) {
//return super.onOptionsItemSelected(item);
switch (item.getItemId()) {
case R.id.aboutUS:
Intent i = new Intent("com.code.myapp.ABOUT");
startActivity(i);
break;
case R.id.preferences:
break;
}
return false;
}

Is there any way I can return a value from a loop and continue from where I left off?

Is there any way I can return a value from a loop and continuing from where I left off ?
In the following snippet, I want to return the current value of currVm. But I am unable to do so.
In the innermost loop of the snippet :
while(c <= currVm) {
allocatedVm(currVm);
c++;
}
a function named allocatedVm is called. I want to return the value of currVm and start again from where I left off. Is there any way out ?
#Override
public int getNextAvailableVm() {
Set<String> dataCenters = confMap.keySet();
for (String dataCenter : dataCenters) {
LinkedList<DepConfAttr> list = confMap.get(dataCenter);
Collections.sort(list, new MemoryComparator());
int size = list.size() - 1;
int count = 0;
while(size >= 0) {
DepConfAttr dca = (DepConfAttr)list.get(count);
int currVm = dca.getVmCount();
int c = 0;
while(c <= currVm) {
allocatedVm(currVm); // RETURN currVm
c++;
}
count++;
size--;
}
}
}
The best approach would probably be to write a method returning an Iterable<Integer>. That's not as easy in Java as it is in languages which support generator functions (e.g. C# and Python) but it's still feasible. If the code is short, you can get away with a pair of (nested) anonymous inner classes:
public Iterable<Integer> foo() {
return new Iterable<Integer>() {
#Override public Iterator<Integer> iterator() {
return new Iterator<Integer>() {
// Implement hasNext, next and remove here
};
}
};
}
In your case I'd be tempted to break it into a separate non-anonymous class though, just for simplicity.
Anyway, the point of using Iterable is that an Iterator naturally has state - that's its purpose, basically. So it's a good fit for your requirements.
Another rather simpler approach would be to return all of the elements in one go, and make the caller perform the allocation on demand. Obviously that doesn't work well if there could be a huge number of elements, but it would be easier to understand.
not sure i understand what you need, but:
if you wish to notify the caller of the method that you've got a value during the running of the method, but don't wish to exit the method just yet, you can use listeners.
just create an interface as a parameter to your function, and have a function inside that will have the object as a parameter.
example:
interface IGotValueListener
{
public void onGotValue(MyClass obj);
}
public int getNextAvailableVm(IGotValueListener listener)
{
...
if(listener!=null)
listener.onGotValue(...);
}
now , for calling the method, you do:
int finalResult=getNextAvailableVm(new IGotValueListener ()
{
... //implement onGotValue
};
You can return from anywhere in your method , by just putting the return keyword. If you want to put a functionality to resume ur method from different places then u need to factor ur method in that way. You can use labels and if statements, set some static variables to mark the last execution place. If your application is not multi-threaded then u need not to worry with the use of static variable synchronization. Also if your method is too big and becoming hard to follow/read, then think about breaking it into smaller ones.

Breaking Out Of A Loop Using A Method In Java

I am trying to use a method to double check before a user exits a while loop in my program.
private static Scanner input = new Scanner(System.in);
public static void ays() {
System.out.println("Are you sure?");
String ays = input.nextLine();
if (ays.equals("Yes")) {
break;
} else {
continue;
}
}
Upon running the program, I get the error break outside switch or loop, and continue outside switch or loop. Is there any way to achieve my goal here?
I guess you are invoking ays() inside a while loop. Let the return type of ays() be boolean and let it return either true or false. Invoke ays() from inside the while loop and based on the value returned by ays(), you continue or break out of the loop.
while (true) {
//Do Something
if (ays()) {
continue();
} else {
break();
}
}

Call methods in a random unique order?

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.

Categories

Resources