Java, questions about switches and cases? - java

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
}

Related

Can I use the same number for 2 cases in old versions in Java?

Can I use the same number for 2 cases in a switch statement in old versions in Java?
int rand = 3;
switch(rand)
{
case 3: System.out.print("***");
case 3: System.out.print("###");
default: System.out.println("&&&");
}
I am using the Java version 15.0.1 and it is not working.
This will not be possible as switch needs a single option for a particular input. You can either use one option like below.
int rand = 3;
switch(rand)
{
case 3: System.out.print("***");
default: System.out.println("&&&");
}
or concatenate both together like below
int rand = 3;
switch(rand)
{
case 3: System.out.print("***###");
default: System.out.println("&&&");
}

Switch case grouping cases

If we take this code as an example :
switch (PeriodEnum.getEnum(month).getValue()) {
case 0: // Calendar.JANUARY
case 2: // Calendar.MARCH
case 4: // Calendar.MAY
case 6: // Calendar.JULY
case 7: // Calendar.AUGUST
case 9: // Calendar.OCTOBER
case 11: // Calendar.DECEMBER
nbDays = 31;
break;
case 3: // Calendar.APRIL
case 5: // Calendar.JUNE
case 8: // Calendar.SEPTEMBER
case 10: // Calendar.NOVEMBER
nbDays = 30;
break;
What is the difference between the previous code and the code below?
switch (PeriodEnum.getEnum(month).getValue()) {
case 0: // Calendar.JANUARY
nbDays = 30;
break;
case 2: // Calendar.MARCH
nbDays = 30;
break;
case 4: // Calendar.MAY
nbDays = 30;
break;
....
}
As a beginner in java , I would love to understand the difference . The main thing I don't understand is how the IDE will detect the case based on the month and associate it?
Thank you
The simple answer is that the compiler is stupid :)
In the first code snippet, the generated JVM code will happily stuff all cases you bundled together into the same branch, and in the second snippet it would, equally happily, stuff each case into its own branch. And even if a set of branches did exactly the same, the compiler doesn't care and won't do the analysis for you.
Now, there is something else to consider in Java, which is that enums are objects like any other... Which means they can have instance variables. Therefore you can do this, and avoid that switch statement altogether:
public enum Calendar
{
JANUARY(30),
FEBRUARY(28),
// etc etc
;
private final int daysInMonth;
Calendar(final int daysInMonth)
{
this.daysInMonth = daysInMonth;
}
public int getDaysInMonth()
{
return daysInMonth;
}
}
In the first part execution will come out of switch statement after break statement, while in second part the program will continue till the last case.
So for the first part whether the value will be 0, 2, 4.... or whatever the assignment nbdays = 31 will be executed and nbdays = 30 will be executed for 1, 3, 5.... Basically it is a way to minimize writing codes for multiple similar statements.
There is no grouping for switch statements.
Consider this arbitrary example:
switch (PeriodEnum.getEnum(month).getValue()) {
case 0: // Calendar.JANUARY
jan();
case 2: // Calendar.MARCH
mar();
case 4: // Calendar.MAY
may();
case 6: // Calendar.JULY
jul();
case 7: // Calendar.AUGUST
aug();
case 9: // Calendar.OCTOBER
oct();
case 11: // Calendar.DECEMBER
dec();
break;
If the switch value is 0, then jan(), mar(), may(), jul(), aug(), oct(), and dec() ALL execute.
If the switch value is 9, then only oct(), and dec() execute.
See what I mean about it not being grouping?
Just like if, while, and for, switch statements were a way of avoiding goto statements.
We idiomatically use them as a map, or a grouping or whatever, but that's not what they literally are. They are literally: Start where the case matches, then exit at break/continue/return/throw. The process of continuing from one case to the next is called "falling through"
To save some code, wrap your switch in a method and instead of assigning a variable and breaking, just return the value and skip the intermediate variable.

How to stop JOptionPane from choosing last case?

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.

Random image in a table view

I have a TableView with 4 parts of the field. which in every field filled images A, B, C and D. You can see in the image below :
My question is how do I make the image appear randomly when the activity start ? Like this one :
Thanks for the questions !
You can always use the static random-method in the Math-class and then create a switch structure
int square = ((int)(Math.random() * 4) + 1);
switch (square) {
case 1:
// .. code
break;
case 2:
// .. code
break;
case 3:
// .. code
break;
case 4:
// .. code
break;
}
You can use
int min = 1;
int max = 4;
Random r = new Random();
int i = r.nextInt(max - min + 1) + min;
switch(i) {
case 0:
// .. code
break;
case 1:
// .. code
break;
case 2:
// .. code
break;
case 3:
// .. code
break;
}
There are many logics... Pseudocode of the one, I can think of right now is as follow:
Step 1: Save image resource info (path) in HashMap with key as 0 to 3.
Step 2: Generate Math.random() between 0 and 3
Step 3: Fetch the image from HashMap with the number got in step 2.
Step 4: Show it in the table.
Hope this helps. All the best.

OR operator in switch-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;
}

Categories