Is there any way i can change it into a switch statement? - java

I need help converting this code into a switch.
if(val >= 0 && val < 10)
cell[0].plus1();
else if(val >= 10 && val < 20 )
cell[1].plus1();
else if(val >= 20 && val < 30 )
cell[2].plus1();
else if(val >= 30 && val < 40 )
cell[3].plus1();
else if(val >= 40 && val < 50 )
cell[4].plus1();
else if(val >= 50 && val < 60 )
cell[5].plus1();
else if(val >= 60 && val < 70 )
cell[6].plus1();
else if(val >= 70 && val < 80 )
cell[7].plus1();
else if(val >= 80 && val < 90 )
cell[8].plus1();
else if(val >= 90 && val < 100 )
cell[9].plus1();
Any help will be highly appreciated.

You don't need a switch statement.
All these statements can be reduced to :
if (val >= 0 && val < 100)
cell[val/10].plus1();

If you really want a switch, you can do:
int v = val/10;
switch(v) {
case 1: cell[1].plus1();
break;
case 2: cell[2].plus1();
break;
case 3: cell[3].plus1();
break;
case 4: cell[4].plus1();
break;
case 5: cell[5].plus1();
break;
case 6: cell[6].plus1();
break;
case 7: cell[7].plus1();
break;
case 8: cell[8].plus1();
break;
case 9: cell[9].plus1();
break;
}
But you could simply do (which is equivalent):
if (val >= 0 && val < 100) cell[val/10].plus1();

Since the cases in a switch statement are determined by equality, an if-else ladder using inequality can not naturally be modelled by a switch statement.
You could list out each of the values in the range and utilize the fall-through nature:
switch (val)
{
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
cell[0].plus1();
break;
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
case 17:
case 18:
case 19:
cell[1].plus1();
break;
...
}
This really is not any improvement to your code and quickly becomes very unwieldy.
Since each of your conditions perform the exact same operation (cell[ X ].plus1()), all you really need is to handle the relationship between the input val and the array index. As Eran's answer shows, in your code this relationship is a simple matter of integer division. I recommend choosing his answer.

int division = val / 10;
now val >=0 && val < 10 equals division = 0
etc...

Related

Anyone have suggestions on how to make this Java switch case more efficient/readable?

It is a pretty standard switch case used within a program that replicates an electric circuit. The main thing I am looking for is easier readability of the code and brevity, without disregarding efficiency.
edit: Didn't realize that I was unclear on the purpose of offset, the way offset works is that it will offset the input char by a number of characters equal to offset which is an integer. So for example if source is 'a' and offset is 2 this will return the value within the paths array at index 2.
char passCurrent(char source)
{
source += offset;
switch(source)
{
case 'a':
return this.paths[0];
case 'b':
return this.paths[1];
case 'c':
return this.paths[2];
case 'd':
return this.paths[3];
case 'e':
return this.paths[4];
case 'f':
return this.paths[5];
case 'g':
return this.paths[6];
case 'h':
return this.paths[7];
case 'i':
return this.paths[8];
case 'j':
return this.paths[9];
case 'k':
return this.paths[10];
case 'l':
return this.paths[11];
case 'm':
return this.paths[12];
case 'n':
return this.paths[13];
case 'o':
return this.paths[14];
case 'p':
return this.paths[15];
case 'q':
return this.paths[16];
case 'r':
return this.paths[17];
case 's':
return this.paths[18];
case 't':
return this.paths[19];
case 'u':
return this.paths[20];
case 'v':
return this.paths[21];
case 'w':
return this.paths[22];
case 'x':
return this.paths[23];
case 'y':
return this.paths[24];
case 'z':
return this.paths[25];
}
return '/';
}
Eliminate the switch and use subtraction after checking the range. Something like,
if (source >= 'a' && source <= 'z') {
return this.paths[source - 'a'];
}
return '/';
And, we can shorten that further with a ternary like
return (source >= 'a' && source <= 'z') ?
this.paths[source - 'a'] : '/';
A char is just a number; the meaning of the number has to do with how characters are laid out in Unicode (the numbers from 0 to 127 were defined a long time ago by ASCII, which got subsumed into Unicode).
Thus, if source is 'a', it actually has the integer value 97. The letters from a to z are all consecutive in Unicode, so b is 98, c is 99, etc.
That means that if you want 0 for a, 1 for b, and so on, you can get it by simple subtraction. Thus:
if (source >= 'a' && source <= 'z') {
return this.paths[source - 97];
}
or, equivalently (and more readably):
if (source >= 'a' && source <= 'z') {
return this.paths[source - 'a'];
}
since 'a' is just another way to write 97.

Generate sets of numbers which only have a difference of 1 from the last set of numbers in a 2d array

Problem: I want to generate random locations on a grid which are touching. The total number of locations is 5. Is there a more efficient/different way of doing the following code:
/*
* 8 1 2
* 7 [original] 3
* 6 5 4
*/
int rand = 1 + (int)(Math.random() * ((8 - 1) + 1));
if(rand >= 2 && rand<= 4)
{
newx++;
}
else if(rand >=6 && rand<=8)
{
newx--;
}
//change y according to number
if(rand == 8 || rand == 1 || rand==2)
{
newy++;
}
else if(rand >= 4 && rand<= 6 )
{
newy--;
}
According to this Thread a switch statement seems to be more efficient for your case. Also it makes your code way more readable.
switch (rand){
case 1: newy++; break;
case 2: newx++; newy++; break;
case 3: newx++; break;
case 4: newx++; newy--; break;
case 5: newy--; break;
case 6: newx--; newy--; break;
case 7: newx--; break;
case 8: newx--; newy++; break;
}
I would advise on the use of Random.nextInt(8) Vs Math.random()*8 (see here why). Because your current requirements seem to allow one "seed" only, you could declare a static Random random = new Random(); in your class, so you just call random.nextInt(8) in your method.
int rand = random.nextInt(8); //0..7
if (rand < 3) //0,1,2
{
newx++;
}
else if (rand < 6) //3,4,5
{
newx--;
}
//change y according to number
if(rand % 3 == 0) //0,3,6
{
newy++;
}
else if(rand % 3 == 1) //1,4,7
{
newy--;
}
As you may notice, the above has the same impact with your approach, but uses the modulo operation mainly for readability purposes, cause mod is not as fast as an if checking.
Small Edit by OP: (result of random represented graphically on x and y axis)
6 3 0
5 [origin] 2
4 7 1

Java nested if to switch statement

I'm having trouble transforming the following nested if statement below, into an equivalent switch statement. If anyone can give me some advice, it would be appreciated.
if (num1 == 5)
myChar = ‘A’;
else
if (num1 == 6 )
myChar = ‘B’;
else
if (num1 = 7)
myChar = ‘C’;
else
myChar = ‘D’;
Pretty straightforward, just use the number as the thing you want to switch on. Your else case becomes the default case.
switch (num1) {
case 5:
myChar = 'A';
break;
case 6:
myChar = 'B';
break;
case 7:
myChar = 'C';
break;
default:
myChar = 'D';
break;
}
If the values follow a simple pattern like this, you don't need a switch at all. For example you can do
myChar = num1 >= 5 && num1 <= 7 ? (char) ('A' + num1 - 5) : 'D';
If num1 is always 5, 6, 7 or 8 you can just do
myChar = (char) ('A' + num1 - 5);
For more details chek the documentation : https://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html
switch(num1){
case 5:
myChar = ‘A’;
break;
case 6:
myChar = ‘B’;
break;
case 7:
myChar = ‘C’;
break;
default:
myChar = ‘D’;
}
In JDK 12, extended switch will allow you to assign a char value directly to the switch. Construct your switch as such:
char myChar = switch(num1) {
case 5 -> 'A';
case 6 -> 'B';
case 7 -> 'C';
default -> 'D';
}

Eliminating only Certain Dates from Java Using Switch Statements [duplicate]

This question already has answers here:
Excluding Dates from Print Loop
(2 answers)
Closed 10 years ago.
I have almost completed my code; however, instead of eliminating solely the dates which fall on Friday and also happen to be the 13th day of the month, it has eliminated every 13th submission. I thought that:
int friday = ((startingDayOfWeek+dayOfYear) % 7);
if (dayOfYear != 13 && friday != 5)
System.out.println(month + "/" + dayOfYear);
dayOfYear++;
Would work, but it is eliminating them all. I understand that there are easier ways to accomplish this; however, I am required to do it in this manner. Here is the full code:
public class LoopDate {
public static void main(String[] args) {
//Denotes that Tuesday is the first day of 2013
int startingDayOfWeek = 2;
int year = 2013;
int numDays = 0;
for (int month = 1; month <= 12; month++) {
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;
}
int dayOfYear = 1;
while (dayOfYear <= numDays)
{
int friday = ((startingDayOfWeek+dayOfYear) % 7);
if (dayOfYear != 13 && friday != 5)
System.out.println(month + "/" + dayOfYear);
dayOfYear++;
}
}
}
}
Your boolean logic is wrong.
if (dayOfYear != 13 && friday != 5)
Should be:
if (dayOfYear != 13 || friday != 5)
You are doing the negative check of "is it friday the 13th". When converting a positive check into a negative check, you need to NOT the conditions (done), and flip the operators (OR becomes AND, AND becomes OR).
Also, when dealing with boolean logic like that, I usually give the segments meaningful names. It 'costs' a variable, but can save you countless hours later on!
boolean isFridayThe13th = (dayOfYear == 13 && friday == 5);
if (!isFridayThe13th) ...

Printing Ordered Dates from a Switch Statement

I am attempting to write a loop that will get its values from my switch statement. I want it to print out the dates in order each on their own line, such as:
1/1
1/2
1/3
...
12/31
I have attempted to write it myself, but I'm not entirely sure how to assign the months in correct order to the 3 cases I have in the switch statement.
Below is the switch statement I am using:
int month = 0;
int yearInt = year;
int totalDays = 0;
switch (month) {
case 1:
totalDays = 30;
break;
case 2:
if (((yearInt % 4 == 0) && !(yearInt % 100 == 0))
|| (yearInt % 400 == 0))
totalDays = 29;
else
totalDays = 28;
break;
default:
totalDays = 31;
break;
Like this? January is assumed 1
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
totalDays = 31;
break;
case 2:
if (((yearInt % 4 == 0) && !(yearInt % 100 == 0))
|| (yearInt % 400 == 0))
totalDays = 29;
else
totalDays = 28;
break;
default:
totalDays = 30;
break;
Note that the fall-through syntax I used is sometimes considered harmfull
You can as well get the desired result using built-in methods:
Calendar c = Calendar.getInstance();
c.set(Calendar.YEAR, yearInt);
c.set(Calendar.MONTH, month);
int totalDays = c.getActualMaximum(Calendar.DAY_OF_MONTH);
Note: Value of month starts from 0 (0 for January, 1 for February..).

Categories

Resources