This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 7 years ago.
making a website in JSP on eclipse:
select[i] is acquired from the previous webpage correctly as a string from 1 to 5
each number represents a subject ie: if select[i]==1 so sub=Maths
I can not switch case on a string so I tried if else .. but sub is always equal to null (the declaration) ?? how can i make sub take the values in the if condition??
for (int i = 0; i < select.length; i++)
{
////
String sub=null;
if(select[i]=="1") {sub="Maths";}
else if (select[i]=="2") {sub="English";}
else if (select[i]=="3") {sub="Physics";}
else if (select[i]=="4") {sub="MI";}
else if (select[i]=="5") {sub="Software";}
////
rs=stmt.executeQuery("SELECT * FROM attends where userid= '"+user_id+"' and cid= '"+select[i]+"' ");
if(rs.next())//can not take it
{
out.println("You can not enroll in '"+sub+"' ");
}
else//can take it
{
int countUpdated =stmt.executeUpdate("INSERT INTO enroll (userid, cid) values ('"+user_id+"', '"+select[i]+"')");
out.println("Successfully enrolled in '"+sub+"' ");
}
}
This is one of the first problems I ever ran into while learning Java: the quandary of == vs equals. Fortunately, once you understand why they're different, it's easy to use them properly.
Whenever you're dealing with objects (as you are in this case), the == operator is used to determine whether two variables actually point to the same object. Objects are dealt with by reference in Java, so if object1 == object2, then the variable object1 actually refers to the same object that the variable object2 refers to.
This is not what you want here. You're trying to determine not whether two String variables point to the same object, but rather whether their contents are the same. For that, you should use the equals method, like so:
String sub=null;
if(select[i].equals("1")) {sub="Maths";}
else if (select[i].equals("2")) {sub="English";}
else if (select[i].equals("3")) {sub="Physics";}
else if (select[i].equals("4")) {sub="MI";}
else if (select[i].equals("5")) {sub="Software";}
This allows you to test whether the contents of sub are the same as the string "1", "2", etc.
And I believe your assumption about switch statements is incorrect: you can switch on a String in Java, and the equals method is used under the hood. So something like this:
String sub;
switch (select[i]) {
case "1":
sub = "Maths";
break;
case "2":
sub = "English";
break;
case "3":
sub = "Physics";
break;
case "4":
sub = "MI";
break;
case "5":
sub = "Software";
break;
default:
sub = null;
break;
}
might be preferable, because that's what switch statements are designed for.
Try this like
switch(select[i]) {
case "1":
sub="Maths";
break;
case "2":
sub="English";
break;
case "3":
sub="Physics";
break;
case "4":
sub="MI";
break;
case "5":
sub="Software";
break;
default:
sub="";
break
}
Related
I have this code with the switch statement which I got from this post, and it works absolutely fine:
String getOrdinal(final int day) {
if (day >= 11 && day <= 13) {
return "th";
}
switch (day % 10) {
case 1: return "st";
case 2: return "nd";
case 3: return "rd";
default: return "th";
}
}
But if I change it to something like the following, it breaks, as all the cases besides case 1 gets executed:
static String getOrdinal(final int day) {
StringBuilder ordinalBuilder = new StringBuilder();
ordinalBuilder.append("<sup>");
if (day >= 11 && day <= 13) {
ordinalBuilder.append("th") ;
}
switch (day % 10) {
case 1: ordinalBuilder.append("st");
case 2: ordinalBuilder.append("nd");
case 3: ordinalBuilder.append("rd");
default: ordinalBuilder.append("th");
}
ordinalBuilder.append("</sup>");
return ordinalBuilder.toString();
}
This prints 2<sup>ndrdth</sup> when I pass in 2. I tried changing the builder to buffer but I got the same response... Could this be a bug or am I making some mistake?
It's a bug in your code. You forgot to put in a break after each case:
switch (day % 10) {
case 1: ordinalBuilder.append("st"); break;
case 2: ordinalBuilder.append("nd"); break;
case 3: ordinalBuilder.append("rd"); break;
default: ordinalBuilder.append("th"); break;
}
I don't see any bug here, at least not in the way the language is working. The behavior of a switch statement, by design, is that it will start executing statements at the case label which matches the argument, and then continue until the end of the block. So
switch (x) {
case 1:
// do thing 1
case 2:
// do thing 2
case 3:
// do thing 3
default:
// do nothing
}
will do both things 2 and 3 if x is 2, and will do things 1, 2, and 3 if x is 1.
To get the behavior you're probably looking for, end each case with a break:
switch (x) {
case 1:
// do thing 1
break;
case 2:
// do thing 2
break;
case 3:
// do thing 3
break;
default:
// do nothing
break;
}
(strictly speaking the break at the very end is unnecessary, but I often put it in out of habit).
The reason you didn't have this problem in the first code example is that return is like a super-break: it has the same effect as break, namely ending execution within the switch block, but it also ends execution of the whole method.
you need to add a 'break' statement in every switch case.
It was worked previously because you made a return from method...
A "break;" statement separates the cases from one another so in order to execute the statements in a specific case just break the case as soon as it comes to an end.
If you don't use break the compiler thinks that it can continue execution of all the cases up to the end of the program.
The first version returns before continuing on in the case statement. The second version needs a break; statement to get the same behavior.
Luckily with the introduction of switch statements on Java 12 which also introduced
"arrow case" labels that eliminate the need for break statements to
prevent fall through (source).
Therefore the modern version of your code looks like the following:
String getOrdinal(final int day) {
if (day >= 11 && day <= 13) {
return "th";
}
return switch (day % 10) {
case 1 -> "st";
case 2 -> "nd";
case 3 -> "rd";
default -> "th";
};
}
I see this question is over 8 years old, but this answer should help anyone landing on this page.
Firstly lets's understand how switch cases work. In C, C++, Java, JavaScript, and PHP while executing switch statements all the cases following the satisfactory case are executed, unlike in Go where only selected case is executed.
For example:
public class Main
{
public static void main(String[] args) {
int day = 11;
switch (day % 10) {
case 1: System.out.println("st");
case 2: System.out.println("nd");
case 3: System.out.println("rd");
default: System.out.println("th");
}
}
}
Currently, day value is set to 11 and hence very first case satisfy the condition, and hence all below cases would be executed. The output should look like the one below:
st
nd
rd
th
Now let's change day value to 13 resulting in the third case to satisfy the condition and hence below output is obtained:
rd
th
Hence if you want to break the code after first satisfactory case is found then put break; condition in the end. In the code mentioned in the question return; does the job of breaking the code.
Also, most of the novice java programmers believe that SWITCH statements are syntactical sugar to IF statements wherein programmers don't have to repetitively mention conditions. But that's not the case as IF's are meant to exit after the execution of satisfactory condition while SWITCH still continues execution.
Switch cases can be utilized to achieve the purpose like one mentioned in below example:
wherein
for Grade A "Excellent!" should be printed
for Grade B and C "Well done" should be printed
for Grade D "You passed \n Try hard next time" should be printed
for Grade F "Try hard next time" should be printed
and if not a valid case i.e grade is found than "Invalid Grade" should be printed.
public class Test {
public static void main(String args[]) {
// char grade = args[0].charAt(0);
char grade = 'C';
switch(grade) {
case 'A' :
System.out.println("Excellent!");
break;
case 'B' :
case 'C' :
System.out.println("Well done");
break;
case 'D' :
System.out.println("You passed");
case 'F' :
System.out.println("Try hard next time");
break;
default :
System.out.println("Invalid grade");
}
System.out.println("Your grade is " + grade);
}
}
Add a break statement at the end of the every line in each case or just use the return statement.
void menu() {
print();
Scanner input = new Scanner( System.in );
while(true) {
String s = input.next();
switch (s) {
case "m": print(); continue;
case "s": stat(); break;
case "[A-Z]{1}[a-z]{2}\\d{1,}": filminfo( s ); break;
case "Jur1": filminfo(s); break; //For debugging - this worked fine
case "q": ; return;
}
}
}
It seems like either my regex is off or that I am not using it right in the case-statement. What I want is a string that: Begins with exactly one uppercase letter and is followed by exactly two lowercase letters, which are followed by at least one digit.
I've checked out the regex API and tried the three variants (greedy, reluctant and possessive quantifiers) without knowing their proper use. Also checked the methods for String without finding a method that seemed pertinent to my needs.
You can't use a regex as a switch case. (Think about it: how would Java know whether you wanted to match the string "[A-Z]{1}[a-z]{2}\\d{1,}" or the regex?)
What you could do, in this case, is try to match the regex in your default case.
switch (s) {
case "m": print(); continue;
case "s": stat(); break;
case "q": return;
default:
if (s.matches("[A-Z]{1}[a-z]{2}\\d{1,}")) {
filminfo( s );
}
break;
}
(BTW, this will only work with Java 7 and later. There's no switching on strings prior to that.)
I don't think you can use regex in switch cases.
The String in the switch expression is compared with the expressions
associated with each case label as if the String.equals method were
being used.
See http://download.oracle.com/javase/7/docs/technotes/guides/language/strings-switch.html for more info.
I have two methods, getOption() and driver().
getOption() takes a String from a scanner, breaks it into individual words, and returns an array of Strings.
driver() then gets the first value of that array, getOption()[0], and begins a while loop based on that first String. While the String does not equal "quit", check if the value matches any switch case. However, when I run it, it can do any of the switch cases, but the quit statement never works. Can anyone give me a hand?
public String[] getOption(){
String optionLine[];
Scanner input = new Scanner(System.in);
System.out.println("Input string\n");
String line = input.nextLine();
optionLine = line.split(" ");
return optionLine;
}
public void driver(){
String option = getOption()[0];
Stats s = new Stats(data);
while (!"quit".equals(option)){
switch (option) {
case "add": //data.put(getOption()[1], getValues());
System.out.println("add");
break;
case "set": System.out.println("set");
break;
case "print": System.out.println(Arrays.toString(data));
break;
case "sum": System.out.println(s.sum());
break;
case "mean": System.out.println(s.mean());
break;
case "stdev": System.out.println(s.standardDeviation());
break;
case "median": System.out.println(s.median());
break;
case "primes": System.out.println(s.primes());
break;
case "summary": System.out.println("summary");
break;
//case "test": System.out.println(Arrays.toString(getValues()));
}
driver();
}
}
You are calling recursively at the end of your while loop the method driver();
no matter if you read getOption or not, you are still coming back inside the method...
that is the reason of the apparently not working while condition...
a very unusual pitfall.
Once you get into your While loop, you never change the value of option. You could change your while to be
while (true){
option = getOption()[0];
Stats s = new Stats(data);
switch (option) {
case "add": //data.put(getOption()[1], getValues());
System.out.println("add");
break;
case "set": System.out.println("set");
break;
case "print": System.out.println(Arrays.toString(data));
break;
case "sum": System.out.println(s.sum());
break;
case "mean": System.out.println(s.mean());
break;
case "stdev": System.out.println(s.standardDeviation());
break;
case "median": System.out.println(s.median());
break;
case "primes": System.out.println(s.primes());
break;
case "summary": System.out.println("summary");
break;
//case "test": System.out.println(Arrays.toString(getValues()));
case "quit": break;
}
}
Note, if you use my answer, you will need to no longer recursively call driver().
You don't seem to be changing the value of option anywhere. You're calling driver() recursively, but that doesn't affect the local variable in the currently executing method which stays the same.
So, one driver() method calls another, which creates its own option variable, unrelated to the option variable of the caller. Basically, only the innermost call to driver() will ever return and you'll be stuck in the while loop of its caller.
Get rid of that recursion, it's unnecessary. Under the switch just call getOption() and update the value of option.
while (!"quit".equals(option)){
// switch statement
option = getOption()[0];
}
This question already has answers here:
Is "else if" faster than "switch() case"? [duplicate]
(14 answers)
Closed 9 years ago.
I need to check a small piece of logic and would highly appreciate if someone can give me some valuable input.
I have two ways of checking my logic and want to know which is more efficient.
1st way:
if(url.equalsIgnoreCase("1")){
url = "aaa";
}
else if(url.equalsIgnoreCase("2")){
url = "bbb";
}
else if(url.equalsIgnoreCase("3")){
url = "ccc";
}
else if(url.equalsIgnoreCase("4")){
url = "ddd";
}
else if(url.equalsIgnoreCase("5")){
url = "eee";
}
else if(url.equalsIgnoreCase("6")){
url = "fff";
}
2nd Way:
int temp = Integer.parseInt(url);
switch (temp) {
case 1:
url = "aaa";
break;
case 2:
url = "bbb";
break;
case 3:
url = "ccc";
break;
case 4:
url = "ddd";
break;
case 5:
url = "eee";
break;
case 6:
url = "fff";
break;
}
Please let me know which is more efficient. Is it bad to use Integer.parseInt(string)?
If your values really are 1-6, the clearest and most efficient way is using an array :
String[] URLS = {...};
url = URLS[Integer.parseInt(url) - 1];
Please let me know which is more efficient.
a switch statement is more efficient is your case
Is it bad to use Integer.parseInt(string)?
No. it's fine. but when you're using java7 you can use String-constants values in your switch cases but not on Android.
Asside from the efficiency: switch looks cleaner in most cases.
In terms of efficiency check this: Case vs If Else If: Which is more efficient?, but Way 2 looks to be a more clean and readable code.
As a general rule, the switch statement produces more efficient bytecode. With Java 7, switch statements with String was introduced, so you don't need to cast it.
In this case, switch is more efficient.
In fact, If you are using Java7, you may directly use string case rather than using Integer.parseInt().
It is not bad using parseInt but it will throw an exception if the string is not an integer.
otherwise, and I think you can see this for yourself, the switch/case is much more readible.
if your if construct would have a final else catching all other cases (including non numeric strings)
then you can do, assuming your ints are always positive
int temp = -1;
try {
temp = Integer.parseInt(str);
} catch (NumberFormatException ex) {
// ignore exception and use -1 as original value for default case
}
Readability and debugability (is that even a word?) are rather subjective but some people (including me) find the switch statement to be more clear. However, in many cases a compiler has a better chance of generating faster code using a switch compared to the if else construct.
The switch statement is faster for the following two reasons.
The switch statement is generally faster than if-else-if construct because the control is directly transferred to the respective case. While in the cases of if-else-if, the all the checks are going to be performed to reach the first matching condition. For example, if you assign temp = 6 the switch statement will execute the respective block directly. The if-else-if construct will iterate through all the conditions.
Calling the equalsIgnoreCase() is more costly than performing the equality check that happens at the background of the case matching.
for such a long list is a switch statement definitely the better choice. The longer the junction is if the better cut off a switch in comparison
Efficiency depends on the matching condition in both cases.Please conform your answer here.
I think an alternative approach would be to use a pre initialized map. It should have the (string)numbers as the key and the url results as value. Then you can simply do
url = map.get(Integer.parseInt(url));
This is probably even a much cleaner version then the long switch statement.
The switch has more features than the if else, because you can fall through cases.
See for details: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html
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);
}
}
will output
Number of Days = 29
So it also depends on your implementation requirements which one you use.
So, all variables in the conditions are static strings. type itself is a string in fact.
switch(type) {
case (INT || TINYINT):
preparedStatement = setInteger(preparedStatement, value, index);
break;
case (BIGINT || LONG):
preparedStatement = setLong(preparedStatement, value, index);
break;
case (DATETIME || TIMESTAMP):
preparedStatement = setTimestamp(preparedStatement, value, index);
break;
case (MEDIUMTEXT || ENUM || TEXT || LONGTEXT || VARCHAR):
preparedStatement = setString(preparedStatement, value, index);
break;
}
First, switch statements on strings are supported in Java 7+, but not in Java 6 and before.
Next, the || operator (the logical-OR operator) only works on boolean values, not String values. But you can get the same code to be run on multiple cases by listing the cases and not breaking until past the relevant code:
switch(type) {
case INT:
case TINYINT:
// This code will run for INT and TINYINT only.
preparedStatement = setInteger(preparedStatement, value, index);
break;
case BIGINT:
case LONG:
// This code will run for BIGINT and LONG only.
preparedStatement = setLong(preparedStatement, value, index);
break;
// etc.
Java 7 example:
public String getTypeOfDayWithSwitchStatement(String dayOfWeekArg) {
String typeOfDay;
switch (dayOfWeekArg) {
case "Monday":
typeOfDay = "Start of work week";
break;
case "Tuesday":
case "Wednesday":
case "Thursday":
typeOfDay = "Midweek";
break;
case "Friday":
typeOfDay = "End of work week";
break;
case "Saturday":
case "Sunday":
typeOfDay = "Weekend";
break;
default:
throw new IllegalArgumentException("Invalid day of the week: " + dayOfWeekArg);
}
return typeOfDay;
}
Further I have never seen an OR statement inside of a switch like that. I would highly recommend not doing that.
Assuming you are using Java SE 7 (or later) and the constants are static final Strings, then the syntax is not Java.
case INT: case TINYINT:
What does this expression evaluate to?
INT || TINYINT
What are the datatypes for INT and TINYINT
I've only ever seen switch used with some primitives (and new in Java 7, string) literals or variables declared as final.
If this isn't throwing a compile error, then the || operator must be defined for whatever datatype those are. But unless that's somehow being resolved at compile time, that operator is not going to be allowed. (Again, this might be something new in Java 7 I'm not aware of.)
If you are trying to do "or" logic, the normative pattern (in pre-7 versions of Java at least), is:
switch(type) {
case INT:
case TINYINT:
preparedStatement = setInteger(preparedStatement, value, index);
break;
case BIGINT:
case LONG:
preparedStatement =
break;
It is supported on and after java 7
You cannot use logical operators in switch statements, even with Strings. You can only test one case at a time.