Passing a value from one case to another in switch statement - java

So here is a sample code :
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
System.out.println("Please type in a number");
Scanner in = new Scanner(System.in);
switch (in.nextInt()){
case 1:
save(in);
break;
case 2:
System.out.println(value);
break;
default:
System.out.println("Default case");
break;
}
in.close();
}
public static String save(Scanner in){
System.out.println("Type in a word");
String value = in.next();
return value;
}
}
In this particular situation all I am trying to do here is to have access to the value that was stored in case 1.

switch statement in all c-like languages including java is very general. It jumps to label according to the value of switch variable and then continues until break statement appears.
I am not sure what did you meant in your long explanation but in following example:
switch(op) {
case ONE:
foo();
case TWO:
bar();
break;
case THREE:
aaa();
qqq();
break;
}
op == ONE first method foo() will be called, then the flow will arrive to block of TWO because no break statement was written in ONE, so bar() will be called. However then the break statement will jump the flow to code that appears just after the switch.
This is a short explanation. For more details find a good book or tutorial and read chapter about switch statement.

Related

Java - Error catching user-input with enums

I have defined an enum in java to use that for validating user input. I am having an issue where if the user puts in something the program just exits and doesn't loop that way I'm expecting it to.
I want to be able to loop until the user has inputted one of the items on the list.
Here's the code in question:
// import System.out
import static java.lang.System.out;
// import scanner for user-input
import java.util.Scanner;
public class AnimalTest {
// enum for user-input
enum animal{
COW,
DUCK,
PIG,
SHEEP
}
public static void main(String[] args){
// create scanner for user input
Scanner userInput = new Scanner(System.in);
do {
// print out menu
out.println("Which animal are you?\nCow\nDuck\nPig\nSheep");
// get user-input and validate against enum
try{
animal selection = animal.valueOf(userInput.nextLine().toUpperCase());
}
catch (Exception e){
out.println("Please type in one of the animals above.");
}
finally{
break;
}
}
while (true);
// switch based on validated user input
switch(selection){
case COW:
cow cow0 = new cow();
cow0.sound();
break;
case DUCK:
duck duck0 = new duck();
duck0.sound();
break;
case PIG:
pig pig0 = new pig();
pig0.sound();
break;
case SHEEP:
sheep sheep0 = new sheep();
sheep0.sound();
break;
}// end switch
}// end main
}// end class
After this, I am going to use a switch and one of the errors the compiler is throwing at me is that the variable selection is not defined so I can use the switch on it, any insight on this aspect as well is apprciated
Aside from the problem highlighted by #mauvecrow's answer, your do/while is useless. a finally block ALWAYS runs, so your while loop will always break at the end. You might as well delete the break, and the entire 'while' construct. Perhaps you intended to loop until a correct answer is entered? Then put the break after the selection = line, within the try block.
I believe your issue is that your "animal selection" variable is defined locally in the try block, thus it is out of scope by the time you get to the switch case.
I have this code (with minor changes for things to run for me) and it works. I declared and initialized (even initialization to null is fine) first.
import static java.lang.System.out;
//import scanner for user-input
import java.util.Scanner;
public class AnimalTest {
// enum for user-input
enum Animal{
COW,
DUCK,
PIG,
SHEEP
}
public static void main(String[] args){
// create scanner for user input
Scanner userInput = new Scanner(System.in);
Animal selection = null;
do {
// print out menu
out.println("Which animal are you?\nCow\nDuck\nPig\nSheep");
// get user-input and validate against enum
try{
selection = Animal.valueOf(userInput.nextLine().toUpperCase());
}
catch (Exception e){
out.println("Please type in one of the animals above.");
}
finally{
break;
}
}
while (true);
// switch based on validated user input
switch(selection){
case COW:
out.println("cow");
break;
case DUCK:
out.println("duck");
break;
case PIG:
out.println("pig");
break;
case SHEEP:
out.println("sheep");
break;
default: out.println("not the expected animal");
}// end switch
}// end main
}// end class

I am writing a Java program that is meant to play a version of 20 questions with the user based on their input

To do this I am using a lot of nested if/else statements.
I have three main branches (living animal, living plant, non-living thing) and each of these have multiple branches. Making it something like 60 different decisions.
I am having a lot of trouble getting it to cooperate, and control all the if/else statements. I don't have much code for it yet because of having to restart so much but currently I am at:
System.out.println("Think of Something");
System.out.println("Is it a living animal, living plant, or non-living thing? ");
String user = get.nextLine();
if (user.equals("living animal")); {
//starts animal tree
System.out.println("Does it have feathers, fur, or neither?");
String user2 = get.nextLine();
if (user2.equals("feathers")); {
System.out.println("is it bigger than a soccer ball?");
}
} else if (user2.equals("fur")); {
System.out.println("is it domesticated?");
// end animal tree
} else if (user.equals("living plant")); {
// start plant tree
System.out.println("is it a tree?");
}
} // end method
} //end program
You are writing out your if statements with this syntax:
if (user2.equals("feathers"));
{
System.out.println("is it bigger than a soccer ball?");
}
However, the body of the if block will always execute because you have a semicolon that finishes the statement prematurely:
if (user2.equals("feathers")); // <-- The semicolon here finishes the if statement, which means the if statement does nothing
{
System.out.println("is it bigger than a soccer ball?"); // <-- This line is ran no matter what the if statement was
}
Basically all you have to do to get the if or else if statements to work correctly is to remove the unwanted semicolons.
As an example for how to a aproach a problem that gets to complex to cope with. It is not ment to be an ready to use program to run out of the box.
Its ment to answer the question how to simplify things when "having a lot of trouble getting it to cooperate, and control all the if/else statements." A strategy for such cases if you want.
Also I overdid things a little for demonstration. In practice, you do what seems convenient. Also: I made everything static for simplicity - in a grown application you surely would use instances instead.
Step 1: You start with a very simple class frame. Simplicity is key. Don't put to much in it. Just sketch what you know you want it to do:
public class TwentyQuestions{
static void mainQuestioning(){
System.out.println("Is it a living animal, living plant, or non-living thing? ");
String user = get.nextLine();
switch(user){
case "living animal" :
askLivingAnimalQuestions();
break;
case "living plant":
askLivingPlantQuestions();
break;
case "non-living":
askNoneLivingQuestions();
break;
default:
handleWrongInput();
}
}
}
Sure, that thing above won't compile as the details are not implemented by now(some methods are missing) - But note how the problem has simplified a lot(no nested if's) and most probably you can imidiately see what it is supposed to do. Keeping it simple, straight forward is key.
Step 2: Now you can easily create the methods you sketched so far. Lets do that:
public class TwentyQuestions{
static void handleWrongInput(){
System.err.println("I am no longer playing with you as you don't answer my question properly");
System.exit(1);
}
static void askLivingAnimalQuestions(){
System.out.println("Does it have feathers, fur, or neither?");
String user = get.nextLine();
switch(user){
case "feathers":
askLivinAnimalWithFeathersQuestions();
break;
case "fur":
askLivinAnimalWithFurQuestions();
break;
default:
handleWrongInput();
}
}
static void askLivingPlantQuestions(){
System.out.println("is it a tree?");
String user = get.nextLine();
if("yes".equals(user)){
System.out.println("So its a tree!");
return;
}
}
static void askNoneLivingQuestions(){
System.out.println("WhateverNoneLivingQuestion ?");
String user = get.nextLine();
switch(user){
//add possible responses here.
default:
handleWrongInput();
}
}
static void mainQuestioning(){
System.out.println("Is it a living animal, living plant, or non-living thing? ");
String user = get.nextLine();
switch(user){
case "living animal" :
askLivingAnimalQuestions();
break;
case "living plant":
askLivingPlantQuestions();
break;
case "non-living":
askNoneLivingQuestions();
break;
default:
handleWrongInput();
}
}
}
Now I broke the problem down even more. But it still/again won't compile because methods are missing for animals with fur and animals with feathers.
Step 3: Implement them as well:
public class TwentyQuestions{
static void handleWrongInput(){
System.err.println("I am no longer playing with you if you don't answer my question properly");
System.exit(1);
}
static void askLivinAnimalWithFeathersQuestions(){
System.out.println("is it bigger than a soccer ball?");
String user = get.nextLine();
//don't know how you want to continue;
//....
}
static void askLivinAnimalWithFurQuestions(){
System.out.println("is it domesticated?");
String user = get.nextLine();
//don't know how you want to continue;
//....
}
static void askLivingAnimalQuestions(){
System.out.println("Does it have feathers, fur, or neither?");
String user = get.nextLine();
switch(user){
case "feathers":
askLivinAnimalWithFeathersQuestions();
break;
case "fur":
askLivinAnimalWithFurQuestions();
break;
default:
handleWrongInput();
}
}
static void askLivingPlantQuestions(){
System.out.println("is it a tree?");
String user = get.nextLine();
if("yes".equals(user)){
System.out.println("So its a tree!");
return;
}
}
static void askNoneLivingQuestions(){
System.out.println("WhateverNoneLivingQuestion ?");
String user = get.nextLine();
switch(user){
//add possible responses here.
default:
handleWrongInput();
}
}
static void mainQuestioning(){
System.out.println("Is it a living animal, living plant, or non-living thing? ");
String user = get.nextLine();
switch(user){
case "living animal" :
askLivingAnimalQuestions();
break;
case "living plant":
askLivingPlantQuestions();
break;
case "non-living":
askNoneLivingQuestions();
break;
default:
handleWrongInput();
}
}
}
Note how all your nested if/else that caused you trouble disapeared.
finish: Now if you additionally implement the missing questioning and add a Scanner "get" that is initialized in a main(String[] args) you should be there. It should be easy now.
Well.. That probably gives you a lot of methods for 20 nested questions: This is due to the numers of posibilities you have. You have to handle that many cases of questions and answers. No way arround it.
Better having them cleanly in their own dedicated, place than stray around somewhere(you tidy up and put everything at its place - the amount of cases/questions you have to handle stays the same).
However in a grown application you may put all your questions and answers in a datastructure like a tree. With that you could avoid the massive amount of methods and have some generalized methods instead that just walk the tree....
[ Also you can just create interim methods that do nothing ("stubs" ) for things you need but have not implemented yet to make it compile while you still developing. ]
Here is the example as a full class, which compiles and does the questioning so far as implemented:
import java.util.Scanner;
/**
*
* #author Kai
*/
public class TwentyQuestions {
static Scanner get = new Scanner(System.in);
static void handleWrongInput() {
System.err.println("I am no longer playing with you if you don't answer my question properly");
System.exit(1);
}
static void askLivinAnimalWithFeathersQuestions() {
System.out.println("is it bigger than a soccer ball?");
String user = get.nextLine();
//don't know how you want to continue;
//....
}
static void askLivinAnimalWithFurQuestions() {
System.out.println("is it domesticated?");
String user = get.nextLine();
//don't know how you want to continue;
//....
}
static void askLivingAnimalQuestions() {
System.out.println("Does it have feathers, fur, or neither?");
String user = get.nextLine();
switch (user) {
case "feathers":
askLivinAnimalWithFeathersQuestions();
break;
case "fur":
askLivinAnimalWithFurQuestions();
break;
default:
handleWrongInput();
}
}
static void askLivingPlantQuestions() {
System.out.println("is it a tree?");
String user = get.nextLine();
if ("yes".equals(user)) {
System.out.println("So its a tree!");
return;
}
}
static void askNoneLivingQuestions() {
System.out.println("WhateverNoneLivingQuestion ?");
String user = get.nextLine();
switch (user) {
//add possible responses here.
default:
handleWrongInput();
}
}
static void mainQuestioning() {
System.out.println("Is it a living animal, living plant, or non-living thing? ");
String user = get.nextLine();
switch (user) {
case "living animal":
askLivingAnimalQuestions();
break;
case "living plant":
askLivingPlantQuestions();
break;
case "non-living":
askNoneLivingQuestions();
break;
default:
handleWrongInput();
}
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
mainQuestioning();
}
}
example run:
Is it a living animal, living plant, or non-living thing?
living animal
Does it have feathers, fur, or neither?
fur
is it domesticated?
yes
BUILD SUCCESSFUL (total time: 30 seconds)
You do not have use the if else correctly may be proper indenting and commenting can also help you in this case.
System.out.println("Think of Something");
System.out.println("Is it a living animal, living plant, or non-living thing? ");
String user = get.nextLine();
// start method
if (user.equals("living animal")); { //starts animal tree
System.out.println("Does it have feathers, fur, or neither?");
String user2 = get.nextLine();
if (user2.equals("feathers")); {
System.out.println("is it bigger than a soccer ball?");
} else if (user2.equals("fur")); {
System.out.println("is it domesticated?");
}
} else if (user.equals("living plant")); { //starts plant tree
System.out.println("is it a tree?");
} // end method

How to call a method with a variable parameter from the main method?

I would like to call the isATens method from my main method but im only able to do that when isATens has no parameter. I'v tried putting the same parameter in the caller, but that does't seem to recognize that either.
public class P1L4 {
public static void main(String[] args) {
P1L4 main = new P1L4();
main.run();
isATens(userInput); //<--- this is what I've tried doing.
}
public void run() {
Scanner scanner = new Scanner(System.in);
System.out.println("Name a tens and i'll test if it's one under 100.");
int userInput = scanner.nextInt();
}
public boolean isATens(int userInput) {
System.out.println(userInput);
switch (userInput) {
case 10 : case 20 : case 30 : case 40 : case 50 : case 60: case 70: case 80: case 90 :
isUnderOneHundred(continued);
default :
System.out.println("Not under one hundred");
}
return true;
}
public boolean isUnderOneHundred(int continued) {
return true;
}
}
There are some Java concepts that you apparently haven't learned yet: Scope and Instance vs. static methods. Read the appropriate chapters of your Java textbook if you have difficulties understanding my following comments.
int userInput = scanner.nextInt(); is declared inside the scope of the run() method, and therefore not visible in the main() method. If you want to see userInput outside of the run() method, I'd make it the return value of that method:
public int run() {
...
int userInput = scanner.nextInt();
return userInput;
}
You're mixing instance and static methods without any visible concept when to use which kind. When you want to call an instance method from a static one, you need to name the instance before the dot, so at least it has to be main.isATens(userInput); instead of isATens(userInput); (after you've solved the userInput issue).
Your program logic is strange, e.g. I'd expect a method like isUnderOneHundred(int continued) to return true if the parameter is under 100, but that method doesn't even have any look at its parameter and returns true for any number you pass in.

Repeat same method and using new value of one parameter

I'm trapped within this certain predicament of mine and I would gladly accept any suggestion. So here it is:
I'm currently working in a method where a certain variable is assigned a specific value in the beginning part of the method. During the course of the method, that variable is used as a parameter by an external component which basically returns a result code. In one of those result codes, I have to change the value of the prior mentioned variable and repeat the whole process using the new value. The concept is as follows but I have simplified it as much as possible:
public void myMethod (String args[]) {
String server;
server = "some value";
switch (someExternalOperation(server)) {
case 1:
//process....
break;
case 2:
server = "new value";
//repeat myMethod using new value of server String variable
break;
}
}
public int someExternalOperation (String str) {
//after several operation
return 1; //example purposes
}
By the way, I have checked and researched things like goto and other alternative. I may have overlooked some results and ended up asking here. Any help would be much appreciated. Thank you.
One simple option is to have a private overload taking the server parameter - then you can call it recursively:
public void myMethod(String args[]) {
myMethod(args, "some value");
}
private void myMethod(String[] args, String server) {
switch (someExternalOperation(server)) {
case 1:
// process....
break;
case 2:
myMethod(args, "new value");
break;
}
}
You need to make sure that isn't going to recurse infinitely, of course.
Another option would be to just have a loop inside your method:
public void myMethod (String args[]) {
String server = "some value";
while (true) { // Or ideally a different condition...
switch (someExternalOperation(server)) {
case 1:
// process....
// Done! Exit the method...
return;
case 2:
server = "new value";
// We'll now continue to the next iteration of the loop
break;
default:
// ?
}
}
}
I figured a way instead to address. Thanks everyone for reading. I'll just simply use the external operation and check if it will return case 2.
public void myMethod (String args[]) {
String server;
server = "some value";
if (someExternalOperation(server) == 2)
server = "new value";
switch (someExternalOperation(server)) {
case 1:
//process....
break;
}
}
public int someExternalOperation (String str) {
//after several operation
return 1; //example purposes
}
Thanks for your help anyway.

Returning a result of type String (Java)

I have a problem returning a result of String type in Java.
Here is the whole code
import java.util.*;
public class Multiplication
{
static Random randomNumbers = new Random();
static Scanner input = new Scanner(System.in);
static int answer;
public static void multiplication()
{
createQuestion(); //display first question
int guess; //student's answer
System.out.print("Your answer is (-1 to quite): ");
guess = input.nextInt();
while(guess != -1)
{
checkAnswer(guess);
System.out.print("Your answer is (-1 to quite): ");
guess = input.nextInt();
}
} //end method multiplication
//create new question
public static void createQuestion()
{
int num_1 = randomNumbers.nextInt(10);
int num_2 = randomNumbers.nextInt(10);
answer = num_1 * num_2;
System.out.printf("How much is %d times %d?\n", num_1, num_2);
}//end method createQuestion
public static String createResponse(boolean correct)
{
if (correct)
switch(randomNumbers.nextInt(4))
{
case 0:
return ("Very good!");
case 1:
return("Excellent!");
case 2:
return("Nice work!");
case 3:
return ("Keep the good work");
} //end switch
//otherwise, assume incorrect
switch(randomNumbers.nextInt(4))
{
case 0:
return("No. Please try again.");
case 1:
return("Wrong. Try once more.");
case 2:
return("Don't give up!");
case 3:
return("No. Keep trying.");
}//end switch
}//end method createResponse
//check in the student answer correctly
public static void checkAnswer(int guess)
{
if(guess != answer)
{
System.out.println(createResponse(false));
}
else
{
System.out.print(createResponse(true));
createQuestion();
}
}//end method checkAnswer
}//end class Multiplication
And here is the main method
public class MultiplicationTest {
public static void main(String[] args) {
Multiplication app = new Multiplication();
app.multiplication();
}
}
The problem is in the createResponse(boolean correct) method. Here JDE is saying that "This method must return a result of type String". I have mentioned there String type return. But the program is not being executed. Showing a red line under the method createResponse(boolean correct).
Does anybody where I have messed up?
Thanks in advance!
The compiler cannot assert that your method returns a String.
This is because your switch-case may fail to return anything.
You can satisfy the compiler by placing a
return null;
at the end of your method.
The method createResponse might not always reach a return statement in your code. If none of the cases in your second switch statement applies, it will reach the bottom of the code block without returning.
Just make sure you return something at the end of the method (or find another nice solution):
return "";
}//end method createResponse
It's because if none of the conditions in either of the switch statements were met there would be nothing to return. Try something like:
public static String createResponse(boolean correct)
{
String result = null;
if (correct)
switch(randomNumbers.nextInt(4))
{
case 0:
result = "Very good!";
// Insert the rest of the code here, assigning to result rather than returning as above.
return result;
}
you are missing the 'else' part for the 'if' and the 'default' case for the 'switch-case' in the createResponse method.
edit:
ok, the 'else' is not necessary, but I missed that in the first place. the indentation of the second 'switch' is confusing. please use parentheses to avoid this.
Furthermore, the compiler believes that it could happen that none of the 'case' branches will get executed since it is not aware of the nextInt returning Integers in the range of 0..3. you'll need to add the default case to satisfy the compiler.
Compiler is not smart enough yet to know that nextInt(4) may return only 0,1,2 and 3 so it assumes that for case like 5 you current code will not return anything, but if method declares that it will return some value must guarantee that some value will always be returned.
To solve this problem you can change case 3: to default:. This would make compiler assume that even for cases which are not 0,1,2 some value will be returned.
Also it seems that your code would be cleaner if you would use else and additional curly brackets like
public static String createResponse(boolean correct) {
if (correct){
switch (randomNumbers.nextInt(4)) {
case 0:
return ("Very good!");
case 1:
return ("Excellent!");
case 2:
return ("Nice work!");
default:
return ("Keep the good work");
}
} else {
switch (randomNumbers.nextInt(4)) {
case 0:
return ("No. Please try again.");
case 1:
return ("Wrong. Try once more.");
case 2:
return ("Don't give up!");
default:
return ("No. Keep trying.");
}
}// end switch
}// end method createResponse
BTW you can simplify your code a little by using arrays which would store your responses. This way your code could look like
private static String[] good = { "Very good!",
"Excellent!",
"Nice work!",
"Keep the good work" };
private static String[] bad = { "No. Please try again.",
"Wrong. Try once more.",
"Don't give up!",
"No. Keep trying." };
public static String createResponse(boolean correct) {
if (correct)
return good[randomNumbers.nextInt(4)];
else
return bad[randomNumbers.nextInt(4)];
}
or even
public static String createResponse(boolean correct) {
return correct ? good[randomNumbers.nextInt(4)]
: bad[randomNumbers.nextInt(4)];
}

Categories