I am trying to do the following for a Java switch method with a series of JUnit Asserts but am stuck on using "less than" and "greater than" for two cases (see string/int error below), and am not sure how to use the ">" and "<" in my cases.
Here is the exercise followed by my code, followed by the error.
/*
Create a method which uses a switch statement to return a String representing the int passed in as a parameter to the method:
• given 1 return "One"
• given 2 return "Two"
• given 3 return "Three"
• given 4 return "Four"
• given an integer > 4, return "Too big"
• given an integer < 1, return "Too small"
*/
#Test
public void switchIntExample() {
assertEquals("One", stringRepInt(1));
assertEquals("Two", stringRepInt(2));
assertEquals("Three", stringRepInt(3));
assertEquals("Four", stringRepInt(4));
assertEquals("Too big.", stringRepInt(>4));
// assertEquals("Too small.", stringRepInt(<4));
}
//Switch statement for above:
public String stringRepInt(int numberSize) {
String numVar = null;
switch (numberSize) {
case 1:
numVar = "One";
break;
case 2:
numVar = "Two";
break;
case 3:
numVar = "Three";
break;
case 4:
numVar = "Four";
break;
//TODO: question on how to do LESS THAN and GREATER THAN:
// error line:
case (numVar > 4):
numVar = "Too big.";
break;
default:
break;
}
System.out.println(numVar);
return numVar;
}
ERROR:
Error:(293, 27) java: bad operand types for binary operator '>'
first type: java.lang.String
second type: int
case statements only support constant expressions (you cannot do less than, or greater than, in a case and you can't test numVar - the String - with less than). You can use an if and something like
public String stringRepInt(int numberSize) {
String numVar = null;
if (numberSize > 4) {
numVar = "Too big.";
} else {
switch (numberSize) {
case 1:
numVar = "One";
break;
case 2:
numVar = "Two";
break;
case 3:
numVar = "Three";
break;
case 4:
numVar = "Four";
break;
default:
break;
}
System.out.println(numVar);
return numVar;
}
You should add it to the default section, so like this:
default:
numVar = "Too Big";
break;
The purpose of the default section is to deal with all cases not dealt with by the switch cases. You should be taking advantage of that (as #GreenMatt and #FredK mentioned in comments) by putting the 'if checks' in the default section, as follows:
public String stringRepInt(int numberSize) {
String numVar = null;
switch (numberSize) {
case 1:
numVar = "One";
break;
case 2:
numVar = "Two";
break;
case 3:
numVar = "Three";
break;
case 4:
numVar = "Four";
break;
default:
if(numberSize > 4)
numVar = "Too big";
break;
}
System.out.println(numVar);
return numVar;
}
Further, you could add else if (numberSize < 1) numVar = "Too small"; under the if statement if you want to check for number's smallest than one. This is also important because it prevents your method from returning null. (Which currently happens if the user enters a value less than 1)
The resulting code is as follows:
public String stringRepInt(int numberSize) {
String numVar = null;
switch (numberSize) {
case 1:
numVar = "One";
break;
case 2:
numVar = "Two";
break;
case 3:
numVar = "Three";
break;
case 4:
numVar = "Four";
break;
default:
if(numberSize > 4)
numVar = "Too big";
else
numVar = "Too small";
break;
}
System.out.println(numVar);
return numVar;
}
In the error line you are comparing String and int.
error line: case (numVar > 4): numVar = "Too big."; break;
you have declared numVar as String and comparing that with int value 4. Please correct that or I think you are trying to compare numberSize with value 4. Convert that String to int and compare it.
Related
I'm a beginner learning Java, and my teacher gave me this question:
Write a switch statement which assigns a value to char grade based on
the value of int variable score.
A score between 0 and 4 inclusive gets an 'F'.
A score of 5 or 6 gets a 'D'
A score of 7 gets a 'C'
A score of 8 gets a 'B'
A score of 9 or 10 gets an 'A'
Any other score gets an 'X'.
No other code than the switch statement itself should be included.
Here's what I wrote:
switch (grade) {
case 'A':
break;
case 'B':
break;
case 'C':
break;
case 'D':
break;
case 'F':
break;
case 'X':
break;
}
After running it on the website, I found that all cases worked except 'X'. So I tried:
default: grade = 'X'
But that also did not work.
How can I add 'X' as a default for this switch statement, and what can help me prevent myself from making this mistake again?
The switch may be used the other way, score > grade and not grade > ... as you did
static char scoreToGrade(int score) {
switch (score) {
case 0:
case 1:
case 2:
case 3:
case 4:
return 'F';
case 5:
case 6:
return 'D';
case 7:
return 'C';
case 8:
return 'B';
case 9:
case 10:
return 'A';
default:
return 'X';
}
}
Or with the other switch expression
static char scoreToGrade(int score) {
return switch (score) {
case 0, 1, 2, 3, 4 -> 'F';
case 5, 6 -> 'D';
case 7 -> 'C';
case 8 -> 'B';
case 9, 10 -> 'A';
default -> 'X';
};
}
Then call
char grade = scoreToGrade(4);
char grade = scoreToGrade(8);
Welcome to StackOverflow. Reading the requirement, you should rethink what is the purpose of the question. The switch statement shouldn't use the grade as a parameter, but the score. Before executing the function, you only know the score: the input is the score, and the output of your function is the grade. Using the score in the case conditions and return from there the grades. As the code executes sequentially, the last statement should be default, returning the X.
Lets try to explain this as easy as possible.
You want to check the score to assign a grade.
Switch takes a variable, in your case you placed grade, and checks if it matches with the cases, in case the grade is equal to A, to B,C...
If I explained it well, the first problem should be easy to see, you are checking the variable your are trying to assign.
You don't have a value for grade at the start, so its imposible to check a condition.
So you should check score (placing it on the switch), and assign grade inside the cases.
String grade; //no values
int score=4; //The variable we want to check
switch (score) {
case 0:
grade = "F";
break;
case 1:
grade = "F";
break;
case 2:
grade = "F";
break;
case 3:
grade = "F";
break;
case 4:
grade = "F";
break;
case 5:
grade = "D";
break;
case 6:
grade = "D";
break;
case 7:
grade = "C";
break;
case 8:
grade = "B";
break;
case 9:
case 10:
grade = "A";
break;
default:
grade = "X";
}
You can imagine it like a series of if checking for equality:
if(score==0){
grade="F";
}
if(score == 1){
grade="F";
}
if(score == 2){
grade="F";
}
if(score == 3){
grade="F";
}
if(score == 4){
grade="F";
}
if(score == 5){
grade="D";
}
if(score == 6){
grade="D";
}
//and so on
(It would more precise to use else if, but this is an example trying to make it as easy as possible, also doesn't cover all switch functionality, but you can get an idea of what I mean with checking and assigning).
At the end, your grade variable will have a value, cause you assigned it in the switch cases.
You can improve that switch, getting rid of the breaks on the firs 4 cases, so it will work like a "cascade", jumping to the next case until it finds a break:
String grade; //no values
int score=4 //The variable we want to check
switch (score) {
case 0:
case 1:
case 2:
case 3:
case 4:
grade = "F";
break;
case 5:
grade = "D";
break;
case 6:
grade = "D";
break;
case 7:
grade = "C";
break;
case 8:
grade = "B";
break;
case 9:
case 10:
grade = "A";
break;
default:
grade = "X";
}
I'm a relatively new student learning Java programming, but I'd like to ask for some help. The error I'm receiving in my code is stating "variable romanNumeral might not have been initialised."
The intent for this program is for a user to enter a number from 1-39 and then have the appropriate roman numeral value displayed to the user via a dialog box. The code is not complete yet, as I've yet to find a solution to this problem due to the application not letting me compile my code.
Here is the code:
public class exercise4 extends Actor
{
int userNum;
public void act()
{
intInput(userNum);
}
public String intInput(int userNum)
{
String userInput;
String romanNumeral;
userInput = JOptionPane.showInputDialog("Please enter a number to be converted into Roman Numerals.");
userNum = Integer.parseInt(userInput);
switch(userNum)
{
case 1: romanNumeral = "I";
break;
case 2: romanNumeral = "II";
break;
case 3: romanNumeral = "III";
break;
case 4: romanNumeral = "IV";
break;
case 5: romanNumeral = "V";
break;
case 6: romanNumeral = "VI";
break;
case 7: romanNumeral = "VII";
break;
case 8: romanNumeral = "VIII";
break;
case 9: romanNumeral = "IX";
break;
case 10: romanNumeral = "X";
break;
case 11: romanNumeral = "XI";
break;
case 12: romanNumeral = "XII";
break;
case 13: romanNumeral = "XIII";
break;
case 14: romanNumeral = "XIV";
break;
case 15: romanNumeral = "XV";
break;
case 16: romanNumeral = "XVI";
break;
case 17: romanNumeral = "XVII";
break;
case 18: romanNumeral = "XVIII";
break;
case 19: romanNumeral = "XIX";
break;
case 20: romanNumeral = "XX";
break;
case 21: romanNumeral = "XXI";
break;
case 22: romanNumeral = "XXII";
break;
case 23: romanNumeral = "XXIII";
break;
case 24: romanNumeral = "XXIV";
break;
case 25: romanNumeral = "XXV";
break;
case 26: romanNumeral = "XXVI";
break;
case 27: romanNumeral = "XXVII";
break;
case 28: romanNumeral = "XXVIII";
break;
case 29: romanNumeral = "XXIX";
break;
case 30: romanNumeral = "XXX";
break;
case 31: romanNumeral = "XXXI";
break;
case 32: romanNumeral = "XXXII";
break;
case 33: romanNumeral = "XXXIII";
break;
case 34: romanNumeral = "XXXIV";
break;
case 35: romanNumeral = "XXXV";
break;
case 36: romanNumeral = "XXXVI";
break;
case 37: romanNumeral = "XXXVII";
break;
case 38: romanNumeral = "XXXVIII";
break;
case 39: romanNumeral = "XXXIX";
break;
}
return romanNumeral;
}
}
Consider how the code would behave if userNum has a value of 40. The switch statement doesn't have a case that matches such a value, so it would do nothing. Which is what the compiler is complaining about: the variable romanNumeral is not initialized when it's declared, and might not be even after the switch - thus: "variable romanNumeral might not have been initialised."
Two simple fixes: (A) initialize at declaration, e.g. String romanNumeral = "?", or (B) add a default part to the switch, as:
switch(userNum)
{
// other cases first
default: romanNumeral = "?";
}
use default in your switch case. in java you must have initialize a variable before using it. in your code if there is a value where no case matches then the variable will not be initialized.
Add in a default case to your switch statement setting it to some error value. You are getting that warning because it is possible your switch matches none of that and romanNumeral will never get set before it's returned.
String romanNumeral makes a reference to a memory location, but doesn't initialize it (doesn't give it a value). Because you can provide a value of usernum that doesn't cause a value to be set for romanNumeral, you're getting an error. To avoid this, you can add a default case.
In Java, variables defined in some method are not automatically initialized.
Here you have two options:
1. Initialize it using
String romanNumeral = null (or something);
2. Use default in switch
default:
romanNumeral = null (or something);
The error just means that the variable still has no memory allocated in it. so, what you will do to remove the error is just to give it an initial value.This will do :
String romanNumeral = "";
It is important to initialize the variable, object instances or any data structure you use. Sometimes it gives the null error but sometimes it does not even give an error and can give wrong values.
Your question have been answered above but I would like to suggest a modification. Following this table, you can make a HashMap of the roman numbers:
Decimal value (v) Roman numeral (n)
1 I
4 IV
5 V
9 IX
10 X
40 XL
50 L
90 XC
100 C
400 CD
500 D
900 CM
1000 M
Using the hashmap you can calculate the roman number for particular integer.Check the code just to give you an idea to get started:
public static void main(String []args){
int c = 39;int temp =0;
String roman = "";
if(c<40 && C>10)
{
temp = c/10;
c = c%10;
for(int i=0;i<temp;i++)
{
roman = roman+map.get(10);
}
}
if(c<10 && c>5)
{
if(c==9)
{
roman = roman+map.get(9);
}else{
temp = c/5;
c = c%5;
if(temp==1)
roamn += map.get(5);
for(int i=0;i<c;i++)
{
roman = roman+map.get(1);
}
//again you will have to check a case for four the way I did for 9
}
}
}
System.out.println(roman);
}
I seem to forget something or do something wrong, but what? Ans what to do if I want it to say "too small" if the number is less then 1?
public static String doStuff(int num) {
String number;
switch (num) {
case 1:
number = "one";
break;
case 2:
number = "two";
break;
case 3:
number = "thee";
break;
case 4:
number = "four";
break;
default:
number = "Not a day";
break;
}
return number;
}
Can only refer from c#
but you should do fine with something like this:
default:
if (num < 1)
number= "too small";
else
number= "Not a day";
break;
You can not handle it in the switch block, but need to have a check before that like
public static String doStuff(int num){
String number;
if (num<1) {
return "too small";
}
switch(num){
case 1:
number= "o
This question already has answers here:
Using switch statement with a range of value in each case?
(20 answers)
Closed 7 years ago.
I want to compare array length with some int values. I can do it with if else but how to do it with switch because switch is fast and I want to use that in my project
switch (array.length) {
case array.length <= 11: // how to do this
break;
default:
break;
}
With if else I can do this:
if (array.length <= 5) {
//my is code here
}
else if (array.length <= 15) {
//my is code here
}
else if (array.length <= 10) {
//my is code here
}
You can't. switch can only test exact values.
You could do:
switch(array.length) {
case 0: case 1: case 2: case 3:
case 4: case 5: case 6: case 7:
case 8: case 9: case 10: case 11:
// do stuff
break;
default:
break;
}
But why do you want to do this? What makes you think it's faster?
switch is not the same as if (...) { ... } else { ... }. You can only use == within a case. You would have to do something like this:
int length = array.length;
switch (length) {
case 0:
case 1:
case 2:
[...]
case 11:
// your code here
break;
//other cases here
}
Notice the missing break-statements, they are quite important.
I would recommend this tutorial for more details.
You can't do it(as per your example) using switch. Since the values of case are constant expression (case *value*).
Switch statements operate by exact matches rather than comparisons like if does. You can do what you want by introducing a new variable like this:
int value = (array.length <= 11 ? 0 : (array.length <= 20 ? 1 : 2));
switch (value) {
case 0: // 11 or under
break;
case 1: // 12 to 20
break;
case 2: // 21 or more
break;
}
I don't know if this buys you much over if/else statements, but if you find it cleaner to code, you can do it.
In your if/elseif, the if(array.length<=10) will never run because if(array.length<=15) is checked above it.
Doing this with an if/elseif structure would require less lines of code.
If you want to do this using a switch/case statement, this would work:
int length = array.length;
switch(length) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5: {
System.out.println("Case 0<=length<=5 triggered.");
break;
}
case 6:
case 7:
case 8:
case 9:
case 10: {
System.out.println("Case 6<=length<=10 triggered.");
break;
}
case 11:
case 12:
case 13:
case 14:
case 15: {
System.out.println("Case 10<=length<=15 triggered.");
break;
}
default: {
System.out.println("Default case triggered.");
}
}
Sonar gives a major violation error ("Cyclomatic Complexity") for the following code. Following method is used to get the date in a special format, e.g. 14-02-3 (Year-month-weekid).
How can I overcome this violation?
private String finalDateForProject;
public String getFinalDateForProject() {
return finalDateForProject;
}
public void setFinalDateForProject(Integer year,Integer month, Integer weekId) {
String projectMonth;
switch (month) {
case 0: projectMonth = "01";
break;
case 1: projectMonth = "02";
break;
case 2: projectMonth = "03";
break;
case 3: projectMonth = "04";
break;
case 4: projectMonth = "05";
break;
case 5: projectMonth = "06";
break;
case 6: projectMonth = "07";
break;
case 7: projectMonth = "08";
break;
case 8: projectMonth = "09";
break;
case 9: projectMonth = "10";
break;
case 10: projectMonth = "11";
break;
case 11: projectMonth = "12";
break;
default: projectMonth = " ";
break;
}
String yearEdited = year.toString();
yearEdited = yearEdited.replace("20", "");
String projectTrendDate = yearEdited +"-"+projectMonth+"-W"+weekId.toString();
this.finalDateForProject =projectTrendDate;
}
One way to reduce cyclomatic complexity that I see is to replace the switch statement. Just create an array or HashMap that will map month index to number;
public void setFinalDateForProject(Integer year,Integer month, Integer weekId) {
String[] months = new String[] {"01", "02", "03", "04", "05", ...}
// Replace switch statement
String projectMonth = months[month];
// Rest of your code
...
}
Another way to solve this problem will be to replace mapping of numbers to strings with converting integer to String using String.format. Use something like:
String projectMonth = String.format("%02d", month + 1);
A simple way to think about it is, cyclomatic complexity increases the more "branches" you have in your code. So with your switch statement you have a whole lot of branches (13 in fact, if I'm counting right). The switch statement can be replaced with this:
if (month < 0 || month > 11) {
projectMonth = " ";
} else {
month++;
projectMonth = ((month < 10) ? "0" : "") + Integer.toString(month);
}
Note that this still has branches, namely the if/else and ternary ?. But these could probably be removed as well, a good alternative with an array is given in the other answer.
The question shouldn't be "How can I reduce the cyclomatic complexity?", but rather "What is the best way to write this function?". One answer is return String.format("%02d-%02d-W%2d", year-2000, month+1, weekId);.