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();
}
}
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;
}
}
I'm currently working on somekind text-based 'RPG' game. I made two classes, first one is supposed to simulate road from one town to another and doing so there is a possibility that player will encounter enemy. Fighting logic is placed in another class and when player dies I call method which is supposed to load game from previous save or create new character and that works perfectly fine, but even when player died road is continued instead of breaking loop. LeaveTown class looks like this:
public class WorldMap {
boolean running=true;
public void leaveTown(Character character){
EnemyFactory factory = new EnemyFactory();
PerformAtack atack = new PerformAtack();
StringBuilder sb = new StringBuilder();
Random random = new Random();
int progress = 0;
while(running && progress!=100){
try {
System.out.print(sb.append("#"));
System.out.println(progress+"%");
if (random.nextDouble() * 10 < 2) {
atack.performFight(character,factory.generateRandomEnemy());
}
Thread.sleep(500);
}catch(Exception ex){}
progress = progress+5;
}
}
}
As you can see, I'm using while loop which is supposed to break when running variable is set to false or road is finished. When character dies I call method battleLost:
private void battleLost(Character character){
WorldMap map = new WorldMap();
System.out.println("You are dead.\nWould you like to try AGAIN or LOAD your last save");
System.out.println("Please type AGAIN or LOAD");
while(true) {
String choice = sc.nextLine().toUpperCase();
if (choice.equals("AGAIN")) {
map.running = false;
System.out.println("Create new character?");
break;
} else if (choice.equals("LOAD")) {
map.running = false;
save.readFromFile();
break;
} else
System.out.println("Try again.");
}
}
This method sets running variable in class WorldMap to false, but the while loop is continued instead of breaking. Im aware that problem is probably linked to using map.running = false; in wrong way.
I'd glad if anyone could explain me how this problem should be solved.
boolean running=true;
This variable should be part of Character class.
then, your while will just look like:
while(character.isRunning() && progress!=100)
and, within performFight you can update it to false when died.
I guess battleLost() belongs to PerformAtack class. so the local variable map inside the battleLost() does not affect the object that is controlling the road.
You can do two things:
make running static (and public) and then you can reference it from anywhere by the class name like this WolrdMap.runnning = false but this solution has problems if you decide to do things in parallel (e.g. multiple threads). Remmeber: static data is almost always a pitfall for multi-threaded design!
a better solution is to make atack.performFight return a boolean value and assign that value to the running var: running = atack.performFight(... this is better design in terms of thread safety, but you will have to propagate the boolean value from battleLost() (it too will have to return boolean) to `performFight()' and so on
Well,Change the access modifier for variable boolean running=true; to public static boolean running=true;
once you did that you can change this variable to false without creating an instance in order to break the loop, do something like that
private void battleLost(Character character){
WorldMap map = new WorldMap();
System.out.println("You are dead.\nWould you like to try AGAIN or LOAD your last save");
System.out.println("Please type AGAIN or LOAD");
while(WorldMap.running) {
String choice = sc.nextLine().toUpperCase();
if (choice.equals("AGAIN")) {
map.running = false;
System.out.println("Create new character?");
break;
} else if (choice.equals("LOAD")) {
map.running = false;
save.readFromFile();
break;
} else
System.out.println("Try again.");
}
public void breakTheLoop(){
WorldMap.running=false;
}
because of static is a class variable so it's value will be shared between all classes
I am going through the University of Helsinki's Java course and I have a question on one of the examples.
The code in question:
import java.util.Scanner;
public class UserInterface {
private Scanner reader;
public UserInterface(Scanner reader) {
this.reader = reader;
}
public void start() {
while (true) {
String command = reader.nextLine();
if (command.equals("end")) {
break;
} else {
handleCommand(command);
}
}
}
public void handleCommand(String command) {
if (command.equals("buy")) {
String input = readInput("What to buy: ");
System.out.println("Bought!");
} else if (command.equals("sell")) {
String input = readInput("What to sell: ");
System.out.println("Sold!");
}
}
public String readInput(String question) {
while (true) {
System.out.print(question);
String line = reader.nextLine();
if (line.equals("carrot")) {
return line;
} else {
System.out.println("Item not found!");
}
}
}
}
If you choose to buy or sell something that isn't a carrot why does it not run the line directly below the input line in the handleCommand method (printing Bought! or Sold!)? I don't understand how it terminates the conditional in the case that a carrot is not bought or sold. How is the readInput method manipulating the handleCommand method here? Thanks.
The function readInput() is rather oddly defined: it will only return if you enter carrot.
readInput() contains a while loop that keeps looping until the user enters carrot, otherwise it says Item not found! and tries again. The output lines in handleCommand() are only executed when readInput() returns.
Basically your readInput() method returns the String "line" only if the user inputs "carrot" otherwise it will keep on going inside the else part and continue printing "Item not found!". But instead of System.out.println("Item not found!") ,
if you just return that statement then either "carrot" or "Item not found!" will be returned and stored in the "input" variable of handleCommand() method. In that case now it will print your "Bought!" or "Sold!" print statement irrespective whether you choose "carrot" or something else
Basically I would like to build a switchcase statement if check if a user input is a integer , float or a String. I would like to use methods such as hasCheckInt() , hasCheckDouble() to check the respective datatype.
Some of the code is missing yes because I do not know what to put in.
Forgive the java noob.
import java.util.Scanner;
public class helloWorld {
public static void main(String[] args) {
Scanner userInput = new Scanner(System.in);
switch()) {
case 1:
if(userInput.hasNextInt()) {
System.out.println("Int");
}
break;
case 2:
if(userInput.hasNextLine()) {
System.out.println("String");
}
break;
}
}
}
Basically I would like to build a switchcase statement if check if a user input is a integer , float or a String. I would like to use methods such as hasCheckInt() , hasCheckDouble() to check the respective datatype.
You can't, the cases of a switch must be constants, not the results of an expression (including a function call).
Instead, you'll need if/else if/else
if (hasCheckInt(argumentHere)) {
// `hasCheckInt` returned `true`
// ...
}
else if (hasCheckDouble(argumentHere)) {
// `hasCheckDouble` returned `true`
// ...
}
else {
// None of the above matched
}
Why java allows to use the labled break inside a method?
Is there any special purpose or use of this?
I thought it can be only use within the loops and swtches.
public void testMeth(int count){
label:
break label;
}
But below gives a compiler error.
public void testMeth(int count){
break; // This gives an Error : break cannot be used outside of a loop or a switch
}
I don't know the why, but the behaviour is specified in the Java Language Specification #14.15:
Break with no label
A break statement with no label attempts to transfer control to the innermost enclosing switch, while, do, or for statement of the immediately enclosing method or initializer; this statement, which is called the break target, then immediately completes normally.
If no switch, while, do, or for statement in the immediately enclosing method, constructor, or initializer contains the break statement, a compile-time error occurs.
Break with label (emphasis mine)
A break statement with label Identifier attempts to transfer control to the enclosing labeled statement (§14.7) that has the same Identifier as its label; this statement, which is called the break target, then immediately completes normally. In this case, the break target need not be a switch, while, do, or for statement.
Breaks with label enable you to redirect the code after a whole block (which can be a loop), which can be useful in the case of nested loops. It is however different from the C goto statement:
Unlike C and C++, the Java programming language has no goto statement; identifier statement labels are used with break (§14.15) or continue (§14.16) statements appearing anywhere within the labeled statement.
You can use this to break out of nested loops immediately:
out: {
for( int row=0; row< max; row++ ) {
for( int col=0; col< max; col++ )
if( row == limit) break out;
j += 1;
}
}
Using break outside of loops does not make a whole lot of sense, where would you be breaking of? To break out of a void function you can use return as adarshr points out.
You can use labeled breaks to get out of nested loops, like here.
Because there is the return statement for use outside the loops!
public void testMeth(int count){
if(count < 0) {
return;
}
// do something with count
}
I found one crazy use by my self.
public void testMeth(int count){
label: if (true) {
System.out.println("Before break");
if (count == 2) break label;
System.out.println("After break");
}
System.out.println("After IF");
}
OR
public void testMeth(int count){
namedBlock: {
System.out.println("Before break");
if (count == 0) break namedBlock;
System.out.println("After break");
}
System.out.println("After Block");
}
This ignores the "After break".
Here is yet another example of when labels are useful outside the context of a loop:
boolean cond1 = ...
if (cond1) {
boolean cond1 = ...
if (cond2) {
boolean cond3 = ...
if (cond3) {
bar();
} else {
baz();
}
} else {
baz();
}
} else {
baz();
}
...becomes...
label: {
boolean cond1 = ...
if (cond1) {
boolean cond1 = ...
if (cond2) {
boolean cond3 = ...
if (cond3) {
bar();
break label;
}
}
}
baz();
}
A contrived example, obviously, but slightly more readable. My recommendation is that if you feel the need to use a label, pretty much ever, you should otherwise refactor the code.
I strongly discurage the use of a labled break statement. It is almost as bad as a GOTO. A single break; is ok/necessary to end a loop or switch etc. But to my experience: The need for such a labled break is an indicator for a bad control-flow-design.
In most cases, a well placed exception would be more meaningful. But just, if the "Jump-Condition" can be seen as an Error. If you lable your method correctly, you can influence, what can be seen as an Error or not.
If your method is called "getDrink()" and it returns a "milk" object, it is ok. But if your method is called "getWater()", it should throw an Exception instead of returning milk...
So instead of:
public class TestBad {
public static void main(String[] args) {
String[] guys = {"hans", "john"};
myLabel: {
for(String guy: guys) {
String drink = getDrink(guy);
if(drink.equals("milk")) {
// Handle "milk"??
break myLabel;
}
// Do something with "non-milk"
}
}
// Success? Non Success??
}
private static String getDrink(String guy) {
if(guy.equals("hans"))
return "milk";
else
return "water";
}
}
You should use:
public class TestGood {
public static void main(String[] args) {
String[] guys = {"hans", "john"};
try {
handleStuff(guys);
} catch (Exception e) {
// Handle Milk here!
}
}
private static void handleStuff(String[] guys) throws Exception {
for(String guy: guys) {
String drink = getWater(guy);
// Do something with "water"
}
}
private static String getWater(String guy) throws Exception {
if(guy.equals("hans"))
// The method may NEVER return anything else than water, because of its name! So:
throw new Exception("No Water there!");
else
return "water";
}
}
Fazit: Instead of nesting Blocks into Blocks or multiple loops, one should nest methods and use proper exception handling. This enhances readability and reusability.