Multiple/repeating cases in a Java switch statement - java

I would like to know how Java handles multiple identical instances of the same case.
I think the following makes sense, conceptually:
switch (someIntegerValue)
{
case 1:
case 2:
DoSomethingForBothCases();
break;
case 3:
DoSomethingUnrelated();
break;
case 1:
DoSomethingForCase1ThatReliesUponExecutionOfTheEarlierFunctionCall();
break;
case 2:
DoSomethingForCase2ThatReliesUponExecutionOfTheEarlierFunctionCall();
break;
}
Essentially, I would like to have a chunk of code executed for either case 1 or 2 (using fall-through), but then later on, have a chunk of code only executed for case 2.
Rather, is the following necessary, instead?
switch (someIntegerValue)
{
case 1:
DoSomethingForBothCases();
DoSomethingForCase1ThatReliesUponExecutionOfTheEarlierFunctionCall();
break;
case 2:
DoSomethingForBothCases();
DoSomethingForCase2ThatReliesUponExecutionOfTheEarlierFunctionCall();
break;
case 3:
DoSomethingUnrelated();
break;
}
My actual code is more complex, but would use the same principle (i.e. something like "case 1: nope; alright... case 2: yep! execute this code!; case 3: nope; case 1 again?: still nope!; case 2 again?: yep! execute this code; no more cases: All Done!")

Anything wrong with two switch statements?
switch (someIntegerValue) {
case 1:
case 2:
DoSomethingForBothCases();
break;
case 3:
DoSomethingUnrelated();
break;
}
switch (someIntegerValue) {
case 1:
DoSomethingForCase1ThatReliesUponExecutionOfTheEarlierFunctionCall();
break;
case 2:
DoSomethingForCase2ThatReliesUponExecutionOfTheEarlierFunctionCall();
break;
}
That's what I would do.

You cannot repeat cases in a Java switch statement, it is a compile error. You will need to do as you have suggested, which actually looks like a good factoring.

You won't be able to do it. You can't have duplicate cases, the compiler will throw a hissy fit lol. I understand your logic in that you would like to check each case and then continue on and check other cases, but the break statement would pull you out of the switch-case statement anyways. What I would recommend is that you consider using a loop (i.e. for, while) if you want to check different things continuously. Coupling if statements with a loop will help you to execute bits of code before others.
Or if you really like the switch statements, you can create multiple switch-cases so that certain things happen before others.

How About this?
NOTE: I don't know that much Java, only Swift 2
var someIntegerValue = 1
func someSwitch(){
switch (someIntegerValue) {
case 1:
break;
case 2:
DoSomethingForBothCases();
break;
case 3:
DoSomethingUnrelated();
break;
}
}
where you have a two button actions,
some action button NEXT
someIntegerValue +=1 // changes someIntegerValue to next case
someIntegerValue() //loads switch
some action button 2 Back
someIntegerValue -=1 // changes someIntegerValue to next case
someIntegerValue() //loads switch

Related

Fall-through if default is in middle of switch case?

I have a question. In a switch statement, is default tested for last even if it isn't last?
If so, in the following code snippet:
int i = 6;
int a=0, b=0, c=0;
switch (i)
{
case 1:
a++;
case 2:
default:
case 3:
b++;
case 6:
c++;
}
System.out.println(a + " " + b + " " + c);
After matching with case 6, and incrementing the value of c, since there is no break, will it go back to default?
I did try this code and it didn't seemly go to default and a fall-through did not occur. I just wanted to know?
switch is evaluated from matching case to either break or end of switch statement. If you pass 6 it will enter case for 6 and do only one increment. But if you enter 7 it will start from default and fall through to the end of switch doing two increments.
There is no additional testing of case labels beyond the initial testing at the beginning of the switch statement. Once i has been evaluated by the switch statement, control transfers to the case 6: label because that matches i. Statements are then executed in order until the end of the switch statement, or until a break statement is encountered. This means that only c is incremented.
A break statement will only end the execution of the entire switch statement; whether a break statement is present has no effect on retesting the switch expression, because retesting the switch expression will not occur either way.
If you want default to be the case label entered, then i must not match any case label at the start of the switch statement. If i is 99 at the start of the switch statement, then both b and c are incremented (fallthrough occurs).
There is no restriction on where in the order of case labels a default label appears, only that at most one default occurs in a switch statement.
Currently, all of your cases will fall through, as no case has a break; as well, your switch is conditionally based on i, so if you want to see each case, you need to change i.
Utilizing break; should not have any effect on where your cases reside in your switch state, this is also the "case" for default
Edit: As #Ivan mentioned, if fall through is intended, then the placement of your cases will matter

Switch Statement Default Case Fall Through

Here is a small confusion so kindly pardon my ignorance. Here is a code snippet.
public class SwitchTest {
public static void main(String[] args) {
int x = 2;
switch (x) {
case 1:
System.out.println("1");
break;
default:
System.out.println("helllo");
case 2:
System.out.println("Benjamin");
break;
}
}
}
Here, if value of x is 2, only Benjamin is printed. That's perfectly fine. Now lets suppose, i change value of x to 3, not matching any case, than its a fall through from default case. Ain't compiler needs to match every case for 3, by that time CASE 2 will be passed, than why it goes back to default and prints hello Benjamin. Can someone explain please?
Thanks,
You need to add a break; statement to break out of the switch block.
switch (x) {
case 1:
System.out.println("1");
break;
default:
System.out.println("helllo");
break; // <-- add this here
case 2:
System.out.println("Benjamin");
break;
}
Generally speaking, it is also better coding practice to have your default: case be the last case in the switch block.
In this case, the switch is following the pattern:
x==1? No, check next case
default? Not done yet, check other cases
x==2? No, check next case
//No more cases, so go back to default
default? Yes, do default logic
// no break statement in default, so it falls through to case 2: logic without checking the case
output case 2 logic
break
Notice how the block will jump over the default case, and save it until a later time unless we have exhausted all other possible cases.
It prints both strings because you do not have a break in your default case, so it continues into case 2, printing Benjamin. You could fix this by adding a break or moving case 2 above the default case.
'switch' case is other form of 'if-then-else', the default case is for the final else part. It is advisable to write default at the end of switch.
Default is checked as last. Thats why it feels like the compiler 'went' back.

Explanation on Switch Statements

public class g{
public static void main(String [] args){
for(int x = 1; x <17; x +=3){
switch(x){
case -1: case 0: case 1:
System.out.print("Breeze");
case 2: System.out.print("Easy");
case 3:
case 4: System.out.print("As"); break;
case 5: System.out.print("Pie"); break;
case 6: case 7: System.out.print("No");
case 8: System.out.print("Problem");
case 9: break;
case 10: System.out.print("Like");
case 12: System.out.print("Nothing"); break;
case 13:
case 14: System.out.print("phew"); break;
}
System.out.println();
}
}
}
Why is it that it prints out
BreezeEasyAs
As
NoProblem
LikeNothing
phew
I thought it would print the default after each one as in Breezephew for the first one
It starts at 1 and it's going up in 3s (x+=3).
So you get case 1 then case 4, 7, 10, 13, 16
But you don't always have breaks so it falls through to the next case in some cases.
Which is why case 1 actually gives "BreezeEasyAs", it runs case 1,2,3 & 4 before it catches a break.
for the first time when x = 1 it prints Breeze but as there is no break in statement it keep on printing Easy & As so befor it reach the end System.out.println(); you will get BreezeEasyAs in the console and then it runs in similar way ( incremented every time by +3)
so the next time :x = 4 it prints As find the break and again incremented by 3
when
x = 7 it prints No finds no break and prints Problem ( so the console output says NoProblem) hope you can figure out the rest
Here are some points regarding switch-case structures you may benefit;
switch-case is a special structure replacing if-else in some cases.
In major programming languages (java, c++) only primitives,
enumerators could be switched.
case represents nothing but an anchor (or so called label) and for that reason only primitives are used since the jump label has to be known during compile-time.
As case keywork actually represents a jump point, doesn't cause
branching like if-else statements.
Switch does the jumping part (just like goto used in some old
programming languages)
As it works by jumping the execution point, you have to put break
keyword at the point you believe you are done with the case
If you don't put break execution will continue.
default keyword represents all of the case which are not handled, and is usually used for detecting unhandled cases
in your case consider that your are incrementing x by 3 and there is no default. lets consider x = 7; in this case execution will jump to case 7: and continue execution until it reaches a break thus executes everything until case 9 as there is the next break.

Why does "switch" in Java rely on "break"? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
class switch1
{
public static void main(String args[])
{
int a = 10;
switch(a)
{
default: System.out.println("Default");
case -1: System.out.println("-1");
}
}
}
I understand that this program will execute both "default" and "case -1" statements as break is not specified after the matching condition (in this case after "default").
But what I fail to understand is
a) why is break needed in a switch statement?
b) why does it even execute the invalid matching conditions' statements (i.e executing "case -1")) if all it does is matching?
Sometimes you need multiple cases to execute the same function. For example, I am letting a user specify either mode 1 or mode 32 to represent 32-bit mode, and mode 2 or mode 64 for 64-bit mode.
switch (input) {
case 1:
case 32:
/* Do 32-bit related code */
break;
case 2:
case 64:
/* Do 64-bit related code */
break;
default:
System.out.println("Invalid input");
}
This is why breaks are important. They tell the switch statement when to stop executing code for a given scenario. Additionally, the default is generally used for when the switch does not match ANY case.
switch statements without breaks let you do things like this:
// Compute the most significant bit set in a number from 0 to 7
int topBit = -1;
switch(n) {
case 0:
topBit = 0;
break;
case 1:
topBit = 1;
break;
case 2:
case 3:
topBit = 2;
break;
case 4:
case 5:
case 6:
case 7:
topBit = 3;
break;
}
Essentially, it lets you create a set of labels, and have a condition at the top to let you jump to the initial label once. After that, the execution continues until a break, or reaching the end of the switch. This technique is old - it has been around since the assembly times, and by virtue of being included in C has made its way into Java and several other languages.
The break statements are necessary because without them, statements in switch blocks fall through: All statements after the matching case label are executed in sequence, regardless of the expression of subsequent case labels, until a break statement is encountered.
check this documentation : http://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html
From the Java Language Specification section on the break statement:
A break statement transfers control out of an enclosing statement.
and...
a break statement ... always completes abruptly
a) It simply allows transfer of control out of the case statement.
b) The reason why it executes the conditions that aren't what you would expect to be matching is because there are particular conditions where falling through case statements would be considered valid (Taken from The Java Tutorials):
List<String> futureMonths = new ArrayList<String>();
int month = 8;
switch (month) {
case 1: futureMonths.add("January");
case 2: futureMonths.add("February");
case 3: futureMonths.add("March");
case 4: futureMonths.add("April");
case 5: futureMonths.add("May");
case 6: futureMonths.add("June");
case 7: futureMonths.add("July");
case 8: futureMonths.add("August");
case 9: futureMonths.add("September");
case 10: futureMonths.add("October");
case 11: futureMonths.add("November");
case 12: futureMonths.add("December");
break;
default: break;
}
for (String monthName : futureMonths) {
System.out.println(monthName);
}
Which outputs:
August
September
October
November
December
a) why does a switch statement relies heavily on a break statement to achieve its purpose ?
Because that's the way they defined it. It's copied from C. Pascal doesn't have fall-through, so it doesn't have break either. It also has case ranges, which Java lacks. Languages are allowed to be different. Or the same.
b) why does it even execute the invalid matching conditions' statements (i.e executing "case -1"))
Because that's the way they defined it, with fall-through if you don't put a break.
if all it does is matching ?
I don't understand the question. It doesn't do matching. It does an indexed jump to the relevant case, and falls through to the next statement if you don't put a break.
As for a., requiring the use of break allows shorthand notation where common code can be placed at the bottom block. This may make code more readable in some cases.
See "Switch statement fallthrough in C#?" for more information on fallthrough.
As for b., since it matches the default case, that line is executed. Because no break is present in that block, the next line is also executed regardless of a match.
Try
switch (a)
{
case 10: System.out.println("This is 10.");
case 9 : System.out.println("This is 9.");
break;
case 8 : System.out.println("This is 8.");
break;
default: System.out.println("Default");
}
Because there is no break in the matching case, the output is
This is 10.
This is 9.
Compare this with setting a to 11, 9, or 8.
If you add break to a loop, it cancels out of the loop. so for a switch statement it goes to the correct case and once it is there it carries out the code until the break where it will then exit the switch statemnt. If you removed the break it would carry on to the next case and until is sees a break. If there are no break; the code will crash.
So basically it separates different cases
In Switch case the point of interest is the break statement.
Each break statement terminates the enclosing switch statement.
Control flow continues with the first statement following the switch
block. The break statements are necessary because without them,
statements in switch blocks fall through: All statements after the
matching case label are executed in sequence, regardless of the
expression of subsequent case labels, until a break statement is
encountered.
The program SwitchDemoFallThrough shows statements in a switch block that fall through. The program displays the month corresponding to the integer month and the months that follow in the year:
public class SwitchDemoFallThrough {
public static void main(String[] args) {
java.util.ArrayList<String> futureMonths =
new java.util.ArrayList<String>();
int month = 8;
switch (month) {
case 1: futureMonths.add("January");
case 2: futureMonths.add("February");
case 3: futureMonths.add("March");
case 4: futureMonths.add("April");
case 5: futureMonths.add("May");
case 6: futureMonths.add("June");
case 7: futureMonths.add("July");
case 8: futureMonths.add("August");
case 9: futureMonths.add("September");
case 10: futureMonths.add("October");
case 11: futureMonths.add("November");
case 12: futureMonths.add("December");
break;
default: break;
}
if (futureMonths.isEmpty()) {
System.out.println("Invalid month number");
} else {
for (String monthName : futureMonths) {
System.out.println(monthName);
}
}
}
}
This is the output from the code:
August
September
October
November
December
Technically, the final break is not required because flow falls out of the switch statement. Using a break is recommended so that modifying the code is easier and less error prone. The default section handles all values that are not explicitly handled by one of the case sections.
Look Here for complete information about switch
a) Why fall-through / required break in switch?
The fall-through behavior is useful in some cases, but the problem is that it's extra work in the common case. Therefore it's reasonable to expect that the "break" keyword would not be required in a more modern language
So why is it there? To match the behavior of C++ (dominant language at the time Java was designed), which again matches the behavior of C (dominant language at the time C++ was designed). As for C, it (and B and BCPL, its predecessors) usually looks the way it does to make it easier to build an efficient compiler. Basically the way the switch statement works is the natural way to implement it in assembler.
b) The way it behaves follows logically from the decision to use fall-through.

Switch statement not being entered

I'm experiencing a strange problem. I have a case statement, and it is not being entered, at all. I've stepped it through with the Eclipse debugger and it gets the line above and then goes straight to the line after. It compiles and runs with no errors.
This is a general outline:
for (int k = 0; k<9; k++) {
System.out.println("Program is here - #1");
doSomething();
switch (switchcode) {
case 1:
switch (k) {
case 1: case 2: case 3:
doOneOneTwoThree(); //#2
break;
case 4: case 5: case 6:
doOneFourFiveSix(); //#3
break;
default:
System.err.println("error k defaulted in case 1");
break;
}
break;
case 2:
switch (k) {
case 1: case 2: case 3:
doTwoOneTwoThree(); //#4
break;
case 4: case 5: case 6:
doTwoFourFiveSix(); //#5
break;
default:
System.err.println("error k defaulted in case 2");
break;
}
break;
default:
System.err.println("error switchcode defaulted");
break;
}
doSomethingElse();
}
I'm doing something wrong, no doubt, but I really don't know what exactly.
Is it because I am switching on k within a case? I have done this before and it has worked, perhaps luckily.
Is the nesting of case statements within a larger for-loop causing problems?
I saw "Branch Prediction Fail" occasionally whilst I was researching around, I don't know exactly what that is but it might be happening.
Is having break; in the default cases causing problems? I don't think it is because I tried it without them and had the same results.
Sorry for the long code and question. Thanks for ANY guidance.
If Eclipse doesn't hit a line it should, then the source might be out-of-sync with the code compiled by Eclipse.
Try to do a clean & new build.
Restarting Eclipse or reimporting the project might also help.
The most likely explanation is that you are not debugging the compiled code you think you are. What you can see when you are running slightly old classes with new source is that the source will be correct and up to date, but the compiled code will skip to old line numbers which can look sort of right.
I would try to do as clean a build as you can. If that doesn't work try moving the code around. e.g. adding lots of blank lines.

Categories

Resources