Switch statement - java

How can I add conditions into a switch statement?(ex:-Displaying the grade for the average marks)

I recommend using if-else... switch statements can only compare on equality.
With an integer score, you COULD do something like...
switch (score)
{
case 100:
case 99:
case 98:
case 97:
case 96:
case 95:
case 94:
case 93:
case 92:
case 91:
case 90:
grade = 'A';
break;
case 89:
/* ... */
}
See the problem? :-)

You can't. Use an if-else-if-else.

Here is how I use less than greater than in a switch statement. The following is in actionscript 3...
var unknown1:Number = 8;
var unknown2:Number = 2;
var lowerBoundary = 1;
var upperBoundary = 5
switch(true){
case (unknown2 < lowerBoundary || unknown2 > upperBoundary):
trace("value is out of bounds");
break;
case (unknown2 > lowerBoundary && unknown2 < upperBoundary):
trace("value is between bounds");
break;
default:
trace("Out of Luck");
break;
}
Output...
value is between bounds

This question is listed with a Java tag so...
Generic switch statement:
// ... within class scope
private final int CONSTANT_1 = 1;
private final int CONSTANT_2 = 2;
private final int CONSTANT_3 = 3;
// ...
public void doStuff(MyObject myObject){
int variable = myObject.getIntValue();
switch(variable){
case CONSTANT_1:
System.out.println(variable + " is equal to " + CONSTANT_1);
// use a break statement to tell the switch to stop here
// or else it will execute all subsequent cases:
break;
case CONSTANT_2:
System.out.println(variable + " is equal to " + CONSTANT_2);
// what happens if I leave out the break?
case CONSTANT_3:
System.out.println(variable + " is equal to " + CONSTANT_2);
break;
default:
System.out.println(variable + " wasn't equal to anything!");
}
Let's say I run through this 3 times and "myObject.getIntValue()" returns these values in this order; 3, 1, 2, and finally 42. Then the following output would be generated:
First time through using the value '3'...
3 is equal to 3
Second time through using the value '1'...
1 is equal to 1
Third time through using the value '2'...
2 is equal to 2
2 is equal to 3
Fourth time through using the value '42' ...
42 wasn't equal to anything!
Notice the third run has two lines (and one incorrect one) because I left out the break keyword for the second case.
Now in Java 1.5 and up, you can also switch on the Enum type:
public void doStuff(MyObject myObject){
MyEnumType varType = myObject.getEnum();
switch(varType){
case MyTypeOne:
// everything else is the same -- nothing special here.
// put whatever code you want in.
break;
case MyTypeTwo:
// everything else is the same -- nothing special here.
// put whatever code you want in.
break;
case MyTypeThree:
// everything else is the same -- nothing special here.
// put whatever code you want in.
break;
default:
// code for unknown case goes here
}
}

Depending on what your ranges are you can use a formula.
e.g.
switch(score/10) {
case 10: case 9: case 8: return 'A';
case 7: return 'B';
case 6: return 'C';
case 5: return 'D';
default: return 'U';
}

In this example, does the code generate a random number and do something if it's that number or that number.
int num; //Just declares a variable
Random r = new Random(); //This makes an object that generates random numbers.
num = r.nextInt(2); //This "Choose" the random number. The possible numbers are 0 and 1. and the sets the the num variable to the number.
switch(num){
case 0: //This says if the number is 0 then do this.
//put code here.
break;
case 1: //This says if the number is 1 then do this.
//put code here
break;
}
And this is a switch statement that do different things based on the number that randomly gets chosen.

Related

Bad practice when I want to check like this if an int is this number?

I have to check if my int n equals 1 or 2 or 3 or 4 or 5 or 6
Is it bad practice to do it like this:
//n = randomnumber
private final List<Integer> numbers = Arrays.asList(0,1,2,3,4,5,6);
if(numbers.contains(n)){
return;
}
or should I do a switch?
switch(n){
case 1:
return;
break;
case 2:
return;
break;
//...
case 6:
return;
break;
}
I could also do if statmements but I guess I dont have to

'Random' returning value that's not in array?

I'm very new to Java and am writing a method that randomly selects an element from a 2 dimensional array.
The idea is that you give it a 2 dimensional array of 52 cards (13 cards in 4 suites) and you randomly select 4 of them and return their total sum.
The program seems to work fine for the most part but sometimes it will return the card "0 of diamonds". This is not an element in the array I gave the method so not quite sure whats going on here.
I'll reproduce most of the relevant code below:
int [][] cards = {{2,3,4,5,6,7,8,9,10,11,12,13,14},{2,3,4,5,6,7,8,9,10,11,12,13,14},
{2,3,4,5,6,7,8,9,10,11,12,13,14},{2,3,4,5,6,7,8,9,10,11,12,13,14}};
int num1 = randomPick(cards);
sum = sum+num1;
switch(num1){
case 11: System.out.print("Jack of "+ suite+", ");
break;
case 12: System.out.print("Queen of "+ suite+", ");
break;
case 13: System.out.print("King of "+ suite+", ");
break;
case 14: System.out.print("Ace of "+ suite+", ");
break;
default: System.out.print(num1+" of "+ suite+", ");
break;}
public static int randomPick(int[][] array){
int randrow = new Random().nextInt(array.length);
int randcol = new Random().nextInt(array[randrow].length);
switch (randrow){
// Each row corresponds to a different suite of cards
case 1:
suite= "spades";
break;
case 2:
suite = "hearts";
break;
case 3:
suite = "diamonds";
break;
case 0:
suite = "clubs";
break;
}
int element =array[randrow][randcol];
return(element);}
As you can see 0 is an not an element in the array that was passed to the method, how is it sometimes returning 0?
The above implementation of randomPick would not return 0 if the same cards array is passed to it in every call.
It looks like cards array gets modified somewhere down the line and randomPick gets called with updated array? I would recommend adding a logging or sysout in randomPick method if the element is 0, e.g.:
int element =array[randrow][randcol];
if(element == 0){
for(int[] arrayElement : array){
System.out.println(Arrays.toString(arrayElement));
}
}

How do I get a console menu to repeat once I have carried out one function so that I can carry out another without the program closing?

I have set up a console menu like so:
int userOption = printMenu(sc);
while(userOption != 6){
switch(userOption) {
case 1: //function 1
break;
case 2: //function 2
break;
case 3: //function 3
break;
case 4: //function 4
break;
case 5: //function 5
break;
case 6: //
break
default: //statement asking for valid option
}
}
However when I run this, it only allows me to carry out the method I want to properly once and then rather than return to my menu and allow me to continue using other functions on top of the one I have just used, it just keeps repeating the original function I used.
Can anybody help me out and give me some advice?
From what is given here you seem to not get another userinput. To solve it you need to get another userinput after executing the loop.
int userOption = printMenu(sc);
while(userOption != 6) {
switch(userOption) {
case 1: //function 1
break;
case 2: //function 2
break;
case 3: //function 3
break;
case 4: //function 4
break;
case 5: //function 5
break;
case 6: //
break
default: //statement asking for valid option
}
userOption = printMenu(sc);
};
As a little additon:
To save yourself the double input you could simply rewrite the loop to a do while loop:
int userOption = 0;
do {
userOption = printMenu(sc);
switch(userOption) {
case 1: //function 1
break;
case 2: //function 2
break;
case 3: //function 3
break;
case 4: //function 4
break;
case 5: //function 5
break;
case 6: //
break
default: //statement asking for valid option
}
} while(userOption != 6);
adding to your comment, you might not store the value into userOption again, but just ask for the input.

Assigning a name to a number

I'm currently writing a program involving random card selection and I'm wondering if there is a way to get the program to replace the numbers 11, 12, and 13 with jack, queen and king respectively? I could use an if statement to detect values greater than 10 but that would force me to write the same code around 4 times which seems counterproductive. Any and all responses greatly appreciated!
int card0 = (cardGenerator.nextInt(13) + 2);
int winTest = 4;
while(winTest > 0)
{
Object[] highLowEqual = { "higher", "lower", "equal", "Quit" };
Object userChoice = JOptionPane.showInputDialog(null,
"The current card is " + card0 + ". Which do you think the next card will be? Remember: Ace is the highest possible.", "HiLo",
JOptionPane.INFORMATION_MESSAGE, null,
highLowEqual, highLowEqual[0]);
int card1 = (cardGenerator.nextInt(13) + 2);
Have a Card class that knows how to print itself:
public class Card
{
int rank;
// ...
public String toString()
{
switch( rank )
{
case 1: return "Ace";
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10: return "" + rank;
case 11: return "Jack";
case 12: return "Queen";
case 13: return "King";
default: return "INVALID CARD RANK";
}
}
}
Some piece of code has to do the replacement and that code has to go somewhere. As commented by khelwood and answered by clcto, you can possibly override the toString() method and put the logic for replacement in there.

Lots of If conditions in Java

I've just started learning java and have a really basic question. I have a label that I want to change colors when a random integer between 1 and 18 lands on a particular number. These numbers are not odd or even, so I can't use that.
Right now I have this:
if (Random == 1 || Random == 2 || Random == 5 || Random == 7 || Random == 12 || Random == 14 || Random == 16 || Random == 18)
label_number.setForeground(SWTResourceManager.getColor(SWT.COLOR_BLUE));
else if (Random == 3 || Random == 4 || Random == 6 || Random == 8 || || Random == 9 | Random == 10 || Random == 11 || Random == 13 || Random == 15 || Random == 17)
label_wheelNumber.setForeground(SWTResourceManager.getColor(SWT.COLOR_GREEN));
I know it looks silly, and I feel like an idiot doing it this way. What do you recommend? I haven't taken a class so any explanations are extremely useful. Thanks
Here is an example of a switch:
Note the break; when using a switch, the case will fall through. Essentially, case 1: will fall through to the next code block. For example in my code, in case 5: if the break; was not there, it would fall through to the next code block and end up with the second code block containing SWT.COLOR_GREEN being called as well.
switch(Random)
{
case 1:
case 2:
case 5:
label_number.setForeground(SWTResourceManager.getColor(SWT.COLOR_BLUE));
break;
case 9:
case 10:
label_wheelNumber.setForeground(SWTResourceManager.getColor(SWT.COLOR_GREEN));
break;
}
You may use a switch:
switch(Random) {
case 1: case 2: case 5: case 7: case 12: case 14: case 16: case 18:
//something...
break;
case 3: case 4: case 6: case 8: case 9: case 10: case 11: case 13: case 15: case 17:
//something...
break;
default:
//just in case none of the over values was selected
}
If the values may vary fast or you want to allow more values, you can store them in an array or similar:
static final int[] FOREGROUND_BLUE = {1, 2, 5, 7, 12, 14, 16, 18};
static final int[] FOREGROUND_GREEN = {3, 4, 6, 8, 9, 10, 11, 13, 15, 17};
And then perform a search to seek if the value belongs to the specified array:
//using binary search since the data in the array is already sorted
int found = Arrays.binarySearch(FOREGROUND_BLUE, Random);
if (found >= 0) {
//something...
}
found = Arrays.binarySearch(FOREGROUND_GREEN, Random);
if (found >= 0) {
//something...
} else {
//...
}
In case you can even have more options, probably you want to use a cache-like approach and store the data in a Map<Integer, Color>:
static final Map<Integer, Color> colorMap;
static {
Map<Integer, Color> colorMapData = new HashMap<Integer, Color>();
Color blue = SWTResourceManager.getColor(SWT.COLOR_BLUE);
Color green = SWTResourceManager.getColor(SWT.COLOR_GREEN);
colorMapData.put(1, blue);
colorMapData.put(2, blue);
colorMapData.put(3, green);
colorMapData.put(4, green);
colorMapData.put(5, blue);
//...
//this makes colorMap truly constant and its values cannot be modified
colorMap = Collections.unmodifiableMap(colorMapData);
}
And then you just call the value from map:
Color = colorMap.get(Random);
Use a Switch statement:
public class SwitchDemo {
public static void main(String[] args) {
int month = 8;
String monthString;
switch (month) {
case 1: monthString = "January";
break;
case 2: monthString = "February";
break;
case 3: monthString = "March";
break;
case 4: monthString = "April";
break;
case 5: monthString = "May";
break;
case 6: monthString = "June";
break;
case 7: monthString = "July";
break;
case 8: monthString = "August";
break;
case 9: monthString = "September";
break;
case 10: monthString = "October";
break;
case 11: monthString = "November";
break;
case 12: monthString = "December";
break;
default: monthString = "Invalid month";
break;
}
System.out.println(monthString);
}
}
Taken from: Oracle's Java Tutorial.
There may be better options depending on where Random is coming from and in what context this is happening, but one option you have to do basically the same thing with a different syntax is:
switch(Random) {
case 1:
case 2:
case 5:
case 7:
case 12:
case 14:
case 16:
case 18:
label_number.setForeground(SWTResourceManager.getColor(SWT.COLOR_BLUE));
break;
case 3:
case 4:
case 6:
case 8:
case 9:
case 10:
case 11:
case 13:
case 15:
case 17:
label_wheelNumber.setForeground(SWTResourceManager.getColor(SWT.COLOR_GREEN));
break;
}
That is only marginally better than what you have but I think it is at least a little easier to look at.
Use a lookup list:
int[] ALLOW_BLUE = {1,2,5,7,12,14,16,18};
int[] ALLOW_GREEN = {3,4,6,8,9,10,11,13,15,17};
if(Arrays.asList(ALLOW_BLUE).contains(random){
label_number.setForeground(SWTResourceManager.getColor(SWT.COLOR_BLUE));
}
else if(Arrays.asList(ALLOW_GREEN).contains(random){
label_number.setForeground(SWTResourceManager.getColor(SWT.COLOR_GREEN));
}
Switch case will do but another way you can do is
int[] blueArray ={1,2,5,7,12,14,16,18};
if(Utils.arrayContain(blueArray,Random)){//your util method
label_number.setForeground(SWTResourceManager.getColor(SWT.COLOR_BLUE));
}elseif(){
}
Take your possible values in an array and check Random is there in that value or not.
If you use a map you can turn this into a one-liner (eliminate the if/switch completely).
HashMap<Integer, Color> mp = new HashMap<Integer, Color>();
mp.put(1, SWT.COLOR_BLUE);
mp.put(2, SWT.COLOR_BLUE);
...
mp.put(18, SWT.COLOR_BLUE);
mp.put(3, SWT.COLOR_GREEN);
mp.put(4, SWT.COLOR_GREEN);
...
mp.put(17, SWT.COLOR_GREEN);
...
label_number.setForeground(SWTResourceManager.getColor(mp.get(Random)));
Also, name your Random variable differently as it clashes with a class name from the Java API.
A more elegant way would be to place each group of numbers in an ArrayList and then check if the Random number is contained in the array with the contains() method:
if(Arrays.asList(new Integer[]{1, 2, 5, 7, 12, 14, 16, 18}).contains(Random )) {
label_number.setForeground(SWTResourceManager.getColor(SWT.COLOR_BLUE));
} else if (Arrays.asList(new Integer[]{3, 4, 6, 8, 9, 10, 11, 13, 15, 17}).contains(Random)) {
label_wheelNumber.setForeground(SWTResourceManager.getColor(SWT.COLOR_GREEN));
}
For performance concerns you can also declare and store these arrays separately instead of creating them on the fly everytime you want to make the comparison.
For situations where you can't use a switch but you still have some complicated condition to evaluate you can use an "explanatory variable"
// before
if ( a && b || c != d && e > f && g < h && h == 1 ) {
doSomething();
} else if ( i && j || etc ) {
doSomethingElse();
}
//after with a variable
boolean shouldDoSomething = a && b || c != d && e > f && g < h && h == 1;
if ( shuoldDoSomething ) {
doSomething();
} else if ( i && j || etc ) {
doSomethingElse();
}
Or create a method that evaluates the condition:
// after with a method
if ( shouldDoSomething(a,b,c,d,e,f,g,h) ) {
doSomething();
} else if ( shouldDoSomethingElse(i, j, etc )) {
doSomethingElse();
}
...
private boolean shouldDoSomething( boolean a,boolean b,int c,int d,int e,int f,int g,int h) {
return a && b || c != d && e > f && g < h && h == 1;
}
private boolean shouldSoSomethingElse(boolean i, boolean j, boolean etc ) {
return i && j || etc;
}
The objective is to simplify your code allowing you to understand it better and making it easier to modify a less error prone. If using a variable or creating a method is more confusing then continue with the simple evaluation. You can also combine the three:
//
boolean shouldDoX = a || b;
if ( shouldDoX || e != d && inRange(f, g, h ) ) {
doSomething();
}
Again the objective is to make it easier to maintain.
In this example the variables are a, b, c but in real code you should use a short meaningful variable name
if ( inRange(random) ) {
label_number.setForeground(SWTResourceManager.getColor(SWT.COLOR_BLUE));
} else if ( outOfRange(random)) {
label_wheelNumber.setForeground(SWTResourceManager.getColor(SWT.COLOR_GREEN));
}
...
private boolean inRange(int random ) {
// use switch or simple return random == 1 || random == 2 etc.
}
Also, final notes on style: do always use brace on your if's even if they are one line and keep the opening brace in the same line. In Java, variables start with lowercase and are written in camelStyle ( no underscores ). These are just style conventions and will help you to create good habits. Each language has its own conventions, learn them and use them.

Categories