so here is my case to make a long code short.
Let's say, we have a JOptionPane with 3 buttons.
boolean loopGameInterface = true;
while(loopGameInterface){
int chooseGame = JOptionePane........
switch(chooseGame) {
case 0:
case 1:
case 2:
System.exit(0);
}
}
So the problem is, when I click (example) second button, it goes to case 1. That's fine. But when the code inside case 1 is executed, it goes directly to case 2 and exit my program, instead of just looping the gameInterface?
You need to add break; at the end of each case. This is true for all switch statements by the way, not just when you are using a JOptionPane
switch(chooseGame) {
case 0: /* Your code */
break;
case 1: /* Your code */
break;
case 2:
System.exit(0);
default : "Give some default case too"
}
Its because you haven't added the break statement. If you are not adding break all the cases below the case which matches will be executed. For eg:
switch(ch) {
case 1:
/* some code without break */
case 2:
/* some code without break */
case 3:
System.exit(0);
}
In the above example if ch=1 then all case 2 will also be executed and then case 3.
If ch=2 then only case 2 and case 3 will be executed since case 3 is below case 2. So you need to add break after each case.
Let's take a simple switch-case that looks like:
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.someValue :
case R.id.someOtherValue:
// do stuff
break;
}
}
I wonder why it is not allowed to use the || operator? Like
switch (v.getId()) {
case R.id.someValue || R.id.someOtherValue:
// do stuff
break;
}
The switch-case construct is pretty similar to an if-else statement, you can use the OR operator in an if however. What are the backgrounds for a switch-case to not accept this operator?
dude do like this
case R.id.someValue :
case R.id.someOtherValue :
//do stuff
This is same as using OR operator between two values
Because of this case operator isn't there in switch case
What are the backgrounds for a switch-case to not accept this operator?
Because case requires constant expression as its value. And since an || expression is not a compile time constant, it is not allowed.
From JLS Section 14.11:
Switch label should have following syntax:
SwitchLabel:
case ConstantExpression :
case EnumConstantName :
default :
Under the hood:
The reason behind allowing just constant expression with cases can be understood from the JVM Spec Section 3.10 - Compiling Switches:
Compilation of switch statements uses the tableswitch and lookupswitch instructions. The tableswitch instruction is used when the cases of the switch can be efficiently represented as indices into a table of target offsets. The default target of the switch is used if the value of the expression of the switch falls outside the range of valid indices.
So, for the cases label to be used by tableswitch as a index into the table of target offsets, the value of the case should be known at compile time. That is only possible if the case value is a constant expression. And || expression will be evaluated at runtime, and the value will only be available at that time.
From the same JVM section, the following switch-case:
switch (i) {
case 0: return 0;
case 1: return 1;
case 2: return 2;
default: return -1;
}
is compiled to:
0 iload_1 // Push local variable 1 (argument i)
1 tableswitch 0 to 2: // Valid indices are 0 through 2 (NOTICE This instruction?)
0: 28 // If i is 0, continue at 28
1: 30 // If i is 1, continue at 30
2: 32 // If i is 2, continue at 32
default:34 // Otherwise, continue at 34
28 iconst_0 // i was 0; push int constant 0...
29 ireturn // ...and return it
30 iconst_1 // i was 1; push int constant 1...
31 ireturn // ...and return it
32 iconst_2 // i was 2; push int constant 2...
33 ireturn // ...and return it
34 iconst_m1 // otherwise push int constant -1...
35 ireturn // ...and return it
So, if the case value is not a constant expressions, compiler won't be able to index it into the table of instruction pointers, using tableswitch instruction.
You cannot use || operators in between 2 case. But you can use multiple case values without using a break between them. The program will then jump to the respective case and then it will look for code to execute until it finds a "break". As a result these cases will share the same code.
switch(value)
{
case 0:
case 1:
// do stuff for if case 0 || case 1
break;
// other cases
default:
break;
}
I do not know a best approach but I do it as
case 'E':
case 'e':
System.exit(0);
break;
Switch is not same as if-else-if.
Switch is used when there is one expression that gets evaluated to a value and that value can be one of predefined set of values. If you need to perform multiple boolean / comparions operations run-time then if-else-if needs to be used.
Since Java 12 and on it is possible to have multiple values in cases:
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.someValue, R.id.someOtherValue:
// do stuff
break;
}
}
OR
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.someValue, R.id.someOtherValue -> {/* do stuff */}
}
}
You can still do it like this.
switch (v.getId()) {
case R.id.someValue: case R.id.someOtherValue:
// do stuff
break;
}
foreach (array('one', 'two', 'three') as $v) {
switch ($v) {
case (function ($v) {
if ($v == 'two') return $v;
return 'one';
})($v):
echo "$v min \n";
break;
}
}
this works fine for languages supporting enclosures
helps in some cases.
switch(true){
case a == b: break;
case a == 2 || a == 3: break;
default: break;
}
I would like to write some code in java that can in a switch or something calls the same case multiple times, using some code that will be the same for most or all cases in the middle. Right now I have to repeat half of the code for each case because it's surrounded by case sensitive code. The code in my mind would look something like this, variable ranges from 0-3 and break just means stop executing until next call to that case, I understand that it is probably something besides break if it exists,
switch(variable){
case 0:
case 1:
if(other factors)
//add item to next spot in array
case 2:
case 3://all cases
//add items to next 3 spots in array for all cases
break;
case 0:
case 1:
if(other factors)
//add item to next spot in array
case 2:
case 3://all cases
//add more items to next spot in array
break;
case 1:
case 2:
if(other factors2)
//add item to next spot in array
break;
case 3:
//add item to next spot in array
case 0:
case 1:
case 2://all cases
//add items to next spot in array
break;
case 1:
case 2:
if(other factors2)
//add item to next spot in array
break;
case 3:
//add item to next spot in array
}
I'd start with splitting your pseudo switch into real switches:
switch(variable){
case 0:
case 1:
if(other factors)
//add item to next spot in array
case 2:
case 3://all cases
//add items to next 3 spots in array for all cases
}
switch(variable){
case 0:
case 1:
if(other factors)
//add item to next spot in array
case 2:
case 3://all cases
//add more items to next spot in array
}
switch(variable){
case 1:
case 2:
if(other factors2)
//add item to next spot in array
break;
case 3:
//add item to next spot in array
case 0:
}
switch(variable){
case 1:
case 2://all cases
//add items to next spot in array
break;
case 1:
case 2:
if(other factors2)
//add item to next spot in array
}
This should meet your requirements.
I then would extract each switch block in its own method, to make it easier to understand and read.
You might consider extracting all this into a small class hirachy:
class DefaultExecutor{
void do(){
step1();
step2();
step3();
step4();
}
void step1(){//all cases class of the first switch statement}
//... similar methods for the other switcht statements
}
class CaseZeor extends DefaultExecutor{
// override step1-4 as required for special treatment of case 0
}
// ... further classes for cases 1-3
You can do this with multiple switch statements. When you use break; it drops out the switch block in any case.
Switch will not fit for that, you will need to perform the checks with some if-else statements (or some separate switch statements as Peter said).
From JLS:
No two of the case constant expressions associated with a switch statement may have the same value.
So I want to do a certain action 60 % of the time and another action 40% of the time. And sometimes have it doing neither. The best way I can think to do this is through switches and making a bunch of cases. An example is below if this doesn't make any sense to ya'll.
My question is, is there a better way?
Is there a way to just do Case 0-5 does action 1 all in one statement?
Random rand = new Random(50);
switch(rand.nextInt())
{
case 1:
{
do action 1
}
break;
case 2:
{
do action 1
}
break;
case 3:
{
do action 1
}
break;
case 4:
{
do action 1
}
break;
case 5:
{
do action 1
}
break;
case 6:
{
do action 1
}
break;
case 7:
{
do action 2
}
break;
case 8:
{
do action 2
}
break;
case 9:
{
do action 2
}
break;
case 10:
{
do action 2
}
break;
}
Something like this would be much more readable IMO:
if( Math.random() >= probabilityOfDoingNothing ){
if( Math.random() < 0.6 ){
action1;
}else{
action2;
}
}
Re. your question about cases, the following is equivalent to your code:
Random rand = new Random(50);
switch(rand.nextInt())
{
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
{
do action 1
}
break;
case 7:
case 8:
case 9:
case 10:
{
do action 2
}
break;
}
Random rand = new Random(50);
int n = rand.nextInt(11);
if(n<=6)
do action 1
else
do action 2
You need to use nextInt(n) to generate a number between 0 (inclusive) and n (exclusive). In this case we use 11 which gives us a number between 0 and 10. Anything below 6 (60% chance) we do action 1 otherwise do action 2.
See this for more details on the Random class.
Using a switch statement is only useful if you have a lot of actions you want to perform, where the action performed depends on something. For example a different action is performed based on the current month. Its quicker than writing if-else statements.
If you want same action to happen for multiple cases, then don't put break. For example
case 1:
case 2:
do action 1; break;
In this case, action 1 will happen for both case 1 and 2.
All you can do is do not apply break in between like
case 1:
case 2:
case 3:
case 4:
case 5:
do action 1;
break
case 6:
case 7:
do action 2;
break
default : break;
or
use if-else if you have range of value ..
There are many approaches to "random" behavior. Some are easier to implement than others but these sacrifice the entropy bucket. Random() is an expensive operation. Switch is useful for complicated signalling, but for a binary decision if is what you want:
int signal = (int)(System.currentTimeMillis() % 5);
if(signal==0 || signal == 1){
doActionTwo();//one third of the time
}else{
doActionOne();//two thirds of the time
}
Why doesn't the compiler automatically put break statements after each code block in the switch? Is it for historical reasons? When would you want multiple code blocks to execute?
Sometimes it is helpful to have multiple cases associated with the same code block, such as
case 'A':
case 'B':
case 'C':
doSomething();
break;
case 'D':
case 'E':
doSomethingElse();
break;
etc. Just an example.
In my experience, usually it is bad style to "fall through" and have multiple blocks of code execute for one case, but there may be uses for it in some situations.
Historically, it's because the case was essentially defining a label, also known as the target point of a goto call. The switch statement and its associated cases really just represent a multiway branch with multiple potential entry points into a stream of code.
All that said, it has been noted a nearly infinite number of times that break is almost always the default behavior that you'd rather have at the end of every case.
Java comes from C and that is the syntax from C.
There are times where you want multiple case statements to just have one execution path.
Below is a sample that will tell you how many days in a month.
class SwitchDemo2 {
public static void main(String[] args) {
int month = 2;
int year = 2000;
int numDays = 0;
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
numDays = 31;
break;
case 4:
case 6:
case 9:
case 11:
numDays = 30;
break;
case 2:
if ( ((year % 4 == 0) && !(year % 100 == 0))
|| (year % 400 == 0) )
numDays = 29;
else
numDays = 28;
break;
default:
System.out.println("Invalid month.");
break;
}
System.out.println("Number of Days = " + numDays);
}
}
I think it is a mistake. As a language construct it is just as easy to have break as the default and instead have a fallthrough keyword. Most of the code I have written and read has a break after every case.
You can do all sorts of interesting things with case fall-through.
For example, lets say you want to do a particular action for all cases, but in a certain case you want to do that action plus something else. Using a switch statement with fall-through would make it quite easy.
switch (someValue)
{
case extendedActionValue:
// do extended action here, falls through to normal action
case normalActionValue:
case otherNormalActionValue:
// do normal action here
break;
}
Of course, it is easy to forget the break statement at the end of a case and cause unexpected behavior. Good compilers will warn you when you omit the break statement.
Why doesn't the compiler automatically put break statements after each code block in the switch?
Leaving aside the good desire to be able to use the identical block for several cases (which could be special-cased)...
Is it for historical reasons? When would you want multiple code blocks to execute?
It's mainly for compatibility with C, and is arguably an ancient hack from the days of old when goto keywords roamed the earth. It does enable some amazing things, of course, such as Duff's Device, but whether that's a point in its favor or against is… argumentative at best.
The break after switch cases is used to avoid the fallthrough in the switch statements. Though interestingly this now can be achieved through the newly formed switch labels as implemented via JEP-325.
With these changes, the break with every switch case can be avoided as demonstrated further :-
public class SwitchExpressionsNoFallThrough {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int value = scanner.nextInt();
/*
* Before JEP-325
*/
switch (value) {
case 1:
System.out.println("one");
case 2:
System.out.println("two");
default:
System.out.println("many");
}
/*
* After JEP-325
*/
switch (value) {
case 1 ->System.out.println("one");
case 2 ->System.out.println("two");
default ->System.out.println("many");
}
}
}
On executing the above code with JDK-12, the comparative output could be seen as
//input
1
// output from the implementation before JEP-325
one
two
many
// output from the implementation after JEP-325
one
and
//input
2
// output from the implementation before JEP-325
two
many
// output from the implementation after JEP-325
two
and of course the thing unchanged
// input
3
many // default case match
many // branches to 'default' as well
So you do not have to repeat code if you need several cases to do the same thing:
case THIS:
case THAT:
{
code;
break;
}
Or you can do things like :
case THIS:
{
do this;
}
case THAT:
{
do that;
}
In a cascade fashion.
Really bug/confusion prone, if you ask me.
As far as the historical record goes, Tony Hoare invented the case statement in the 1960s, during the "structured programming" revolution. Tony's case statement supported multiple labels per case and automatic exit with no stinking break statements. The requirement for an explicit break was something that came out of the BCPL/B/C line. Dennis Ritchie writes (in ACM HOPL-II):
For example, the endcase that escapes from a BCPL switchon statement was not present in the language
when we learned it in the 1960s, and so the overloading of the break keyword to escape
from the B and C switch statement owes to divergent evolution rather than conscious change.
I haven't been able to find any historical writings about BCPL, but Ritchie's comment suggests that the break was more or less a historical accident. BCPL later fixed the problem, but perhaps Ritchie and Thompson were too busy inventing Unix to be bothered with such a detail :-)
Java is derived from C, whose heritage includes a technique known as Duff's Device .
It's an optimization that relies on the fact that control falls through from one case to the next, in the absence of a break; statement. By the time C was standardized, there was plenty of code like that "in the wild", and it would have been counterproductive to change the language to break such constructions.
As people said before, it is to allow fall-through and it is not a mistake, it is a feature.
If too many break statements annoy you, you can easily get rid of them by using return statements instead. This is actually a good practice, because your methods should be as small as possible (for the sake of readability and maintainability), so a switch statement is already big enough for a method, hence, a good method should not contain anything else, this is an example:
public class SwitchTester{
private static final Log log = LogFactory.getLog(SwitchTester.class);
public static void main(String[] args){
log.info(monthsOfTheSeason(Season.WINTER));
log.info(monthsOfTheSeason(Season.SPRING));
log.info(monthsOfTheSeason(Season.SUMMER));
log.info(monthsOfTheSeason(Season.AUTUMN));
}
enum Season{WINTER, SPRING, SUMMER, AUTUMN};
static String monthsOfTheSeason(Season season){
switch(season){
case WINTER:
return "Dec, Jan, Feb";
case SPRING:
return "Mar, Apr, May";
case SUMMER:
return "Jun, Jul, Aug";
case AUTUMN:
return "Sep, Oct, Nov";
default:
//actually a NullPointerException will be thrown before reaching this
throw new IllegalArgumentException("Season must not be null");
}
}
}
The execution prints:
12:37:25.760 [main] INFO lang.SwitchTester - Dec, Jan, Feb
12:37:25.762 [main] INFO lang.SwitchTester - Mar, Apr, May
12:37:25.762 [main] INFO lang.SwitchTester - Jun, Jul, Aug
12:37:25.762 [main] INFO lang.SwitchTester - Sep, Oct, Nov
as expected.
It is an old question but actually I ran into using the case without break statement today. Not using break is actually very useful when you need to combine different functions in sequence.
e.g. using http response codes to authenticate user with time token
server response code 401 - token is outdated -> regenerate token and log user in.
server response code 200 - token is OK -> log user in.
in case statements:
case 404:
case 500:
{
Log.v("Server responses","Unable to respond due to server error");
break;
}
case 401:
{
//regenerate token
}
case 200:
{
// log in user
break;
}
Using this you do not need to call log in user function for 401 response because when the token is regenerated, the runtime jumps into the case 200.
Not having an automatic break added by the compiler makes it possible to use a switch/case to test for conditions like 1 <= a <= 3 by removing the break statement from 1 and 2.
switch(a) {
case 1: //I'm between 1 and 3
case 2: //I'm between 1 and 3
case 3: //I'm between 1 and 3
break;
}
because there are situations where you want to flow through the first block for example to avoid writing the same code in multiple blocks but still be able to divide them for mroe control. There are also a ton of other reasons.
You can makes easily to separate other type of number, month, count.
This is better then if in this case;
public static void spanishNumbers(String span){
span = span.toLowerCase().replace(" ", "");
switch (span){
case "1":
case "jan": System.out.println("uno"); break;
case "2":
case "feb": System.out.println("dos"); break;
case "3":
case "mar": System.out.println("tres"); break;
case "4":
case "apr": System.out.println("cuatro"); break;
case "5":
case "may": System.out.println("cinco"); break;
case "6":
case "jun": System.out.println("seis"); break;
case "7":
case "jul": System.out.println("seite"); break;
case "8":
case "aug": System.out.println("ocho"); break;
case "9":
case "sep": System.out.println("nueve"); break;
case "10":
case "oct": System.out.println("diez"); break;
}
}
I am now working on project where I am in need of break in my switch statement otherwise the code won't work. Bear with me and I will give you a good example of why you need break in your switch statement.
Imagine you have three states, one that waits for the user to enter a number, the second to calculate it and the third to print the sum.
In that case you have:
State1 - Wait for user to enter a number
State2 - Print the sum
state3 - Calculate the sum
Looking at the states, you would want the order of exaction to start on state1, then state3 and finally state2. Otherwise we will only print users input without calculating the sum. Just to clarify it again, we wait for the user to enter a value, then calculate the sum and prints the sum.
Here is an example code:
while(1){
switch(state){
case state1:
// Wait for user input code
state = state3; // Jump to state3
break;
case state2:
//Print the sum code
state = state3; // Jump to state3;
case state3:
// Calculate the sum code
state = wait; // Jump to state1
break;
}
}
If we don't use break, it will execute in this order, state1, state2 and state3. But using break, we avoid this scenario, and can order in the right procedure which is to begin with state1, then state3 and last but not least state2.
Exactly, because with some clever placement you can execute blocks in cascade.