I am attempting to create it so the user will type in a keyword and it will execute that case. This works fine, but I would like the user to also be able to write after the keyword and it will still find the correct case. For example, the user might input "SEARCH dogs and cats" and it would run the "SEARCH" case.
I attempted to do have a temporary variable that stored only the "SEARCH" portion of the string, but I received an error that it had to be a constant in the switch statements. Is there a workaround or will I have to use if else statements?
Here is some test code with the error:
switch(textField.getText)
{
case SEARCH: case textField.getText().split(" ", 2)[0]: // Error is occuring on the second case statement
// Statements
break;
case Default:
lblOutput.setText("ERROR: NOT FOUND");
}
You need to specify one of three things in a case statement:
A constant
An Enum
Default keyword
Refer to
https://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.11
In addition, you have a "case" within a "case" with no intermediate "switch" statement.
Related
I'm doing some Java homework and I am on a problem that has a code relating to converting test scores to letter grades where errors must be found:
switch(score)
{
case (score > 90):
grade = 'A';
break;
etc...
Everywhere I've read, and everything I've tried in netbeans says boolean functions aren't allowed. Is the error that it should just be an if statement?
The content associated to the case has to compatible with the type of the expression used in the switch.
You use an int (probably) in the switch, so the cases have to be int values (or another type convertible to an int such as a char for example). The problem is that you provide a boolean that is not convertible to an int and whatever it is not what you are looking for.
The JLS.14.11. The switch Statement states indeed :
Given a switch statement, all of the following must be true or a
compile-time error occurs:
Every case constant associated with the switch statement must be
assignment compatible with the type of the switch statement's
Expression (§5.2).
If the two types don't match, you don't want to use a switch but a series of conditional statements (if-else-if) instead of.
According to the JLS, the parameters of the case statements can only be int, short, byte, char, String or Enum literals or constants.
So to answer your question, the given code will not compile and yes, it should be an if statement.
Is there an option in the Eclipse workspace properties to change the order that the "incomplete-switch" warning auto-populates cases within the switch statement? For example, if I have an enum:
enum TraversalType{
PREORDER,
INORDER,
POSTORDER;
}
When you use this and have the switch statement warning auto complete the cases within the body of the switch, it seems to always order alphabetically. Is there an option to change this and use the ordering, like in this example, to look like:
switch(TraversalType pType){
case PREORDER:
break;
case INORDER:
break;
case POSTORDER:
break;
}
every time, instead of just after manually entering the cases?
You can't change the ordering of case statements in the Eclipse auto complete feature of "add missing case statements". However you can sort the enum members alphabetically to match the order of the auto inserted switch cases.
This is the code I have:
public enum Modification {
NONE, SET, REMOVE;
}
boolean foo(){
for (S s : sList) {
final Modification modification = s.getModification();
switch (modification) {
case SET:
case REMOVE:
return true;
/*
case NONE:
break;
*/
}
}
return false;
}
And when the code is as seen above, IntelliJ will say:
'for' statement does not loop less... () Reports any instance of for,
while and do statements whose bodies are guaranteed to execute at most
once. Normally, this is an indication of a bug.
Only if I make the following change, IntelliJ will be happy:
for (S s : sList) {
final Modification modification = s.getModification();
switch (modification) {
case SET:
case REMOVE:
return true;
case NONE:
break;
}
}
Why is my for loop not looping if case NONE: is not included in the switch statement?
I just tried this in eclipse and you end up with a compiler warning on the switch statement.
The enum constant NONE needs a corresponding case label in this enum switch on Modification
To resolve the warning I'm given the following options.
Add default case
Add missing case statements
Add #SuppressWarnings 'incomplete-switch' to foo()
If I add the missing case statement then the warning no longer appears. The same as adding the missing case makes your error warning disappear from intellij.
Without the statement for case NONE you can only see two cases, both of which return true. Without knowing the structure of Modification and the extra value of NONE it looks like this loop would just return true on the first iteration of the loop.
Of course the compiler should actually know that there are more values for Modification than SET and REMOVE so the warning is just for good style. Basically your code works but here's how to improve it.
I would choose to add a default statement rather than the missing case. This would be more future proof in case more values are later added to the enum. E.G.
switch (modification)
{
case SET:
case REMOVE:
return true;
default:
break;
}
Personally I'm not a fan of using the fall through on switch statements. What you gain in making the code concise you lose in legibility IMHO. If someone later comes and adds a case between SET and REMOVE it could introduce a bug. Also, having a return statement mid-way through a method can also cause problems. If someone wants to add some code just before the return they may miss all the places. If the method is very simple then multiple returns is fine but you've stated that this is a simplified example and so if this block of code is complicated I would avoid it.
If you're able to use Java 8 then this looks to be the perfect use case for the new stream API. Something like the following should work.
return sList.stream().anyMatch(
modification -> (modification==Modification.SET || modification==Modification.REMOVE)
);
i assume these are your only three cases right?, so basically its saying you are going to hit one of the first two and instantly return true, therefore not looping, just add a default case and everything should work ok, this is good practice also btw.
basically it cant see a case where it doesnt just return instantly without iterating the loop
I'd say its a false positive.
1st indication:
If you run your code through a debugger - and have elements with NONE modification in the list before an element with other modifications - it will actually loop.
2nd indication:
When you look at the generated bytecode, it transforms the switch statement to (sort of - its not exactly the same)
for (S s : sList) {
Modification modification = s.getModification();
switch (modification.ordinal()) {
case 1:
case 2:
return true;
}
}
If you put that in your code, IntelliJ does not complain.
3rd indication:
the warning dissappears if you put an additional statement before the return, i.e. System.out.println();
switch (modification) {
case SET:
case REMOVE:
System.out.println()
return true;
Seems you tricked the inspection with the missing case label and could simply ignore the warning.
I think that IntelliJ's inspections is wrong. I reported it to JetBrains
Edit : it's fixed
Your switch case always breaks or returns. In the first case, you do nothing aka it falls through. The second case returns which causes both the switch and the loop to stop. In the third case you break the switch statement which causes it to stop. It does not however stop the for loop (aka, it keeps iterating).
Either add specific functionality for the SET case or change your behaviour on the REMOVE and NONE cases.
public enum Modification {
NONE, SET, REMOVE;
}
boolean foo(){
for (S s : sList) {
final Modification modification = s.getModification();
switch (modification) {
case SET:
// This case falls through to the REMOVE case
case REMOVE:
return true; // This statement stops the switch, loop and returns true
case NONE:
break; // This statement stops the switch and continues the loop.
}
}
return false;
}
Your switch is not looping without the NONE case because return breaks the loop and returns a value from the function. break breaks the switch loop but continues the for loop.
By request of OP an extra explanation.
Falling through means the next case will be executed until a stop (break or return) is reached. This makes the following code snippets equivelant:
case SET:
case REMOVE:
return true;
is the same as:
case SET:
return true;
case REMOVE:
return true;
I'm writing a Mad Libs program. In it, there are a variety of stories.. or at least there will be. At the moment, there's only one. But my method that chooses a story has reference to methods I haven't made yet. For some reason, this code will not compile, even though at no point am I calling the unmade methods. Why is this?
Here's the choose a story method.
public void chooseStory (int choice)
{
switch (choice)
{
case 1:
story1();
break;
case 2:
story2();
break;
case 3:
story3();
break;
case 4:
story4();
break;
}
But even if choice is 1, I still get the error:
Exception in thread "main" java.lang.Error: Unresolved compilation problems:
The method story2() is undefined for the type MLServer
The method story3() is undefined for the type MLServer
The method story4() is undefined for the type MLServer
at MLServer.chooseStory(MLServer.java:13)
at MLApp.main(MLApp.java:31)
Why is the JVM evaluating code that's never hit?
Java doesn't know what code will be called. You might aswell upload and use the class-files from a server for example. Apart from that it would be pretty complicated (or even impossible, if user-choices are involved) to predicate which parts of the code will be accessed and which not. And the resulting byte-code would contain references to code that doesn't even exist, which would make compilation and execution pretty complicated.
I have a problem concerning switch/case statements in java in combination with enums.
In my code I want to do something based on the Enum of the type "MatchingMethods" set in the object "currentMethod".
The enum "MatchingMethods" contains several enums in the form
{EXACT_STRING_MATCHING, DEPTH_MATCHING, [...]}
Now the strange thing is though the object "currentMethod" contains an enum of the type "EXACT_STRING_MATCHING" not only the first case is executed but also the second one.
I know there is no break statement after the code of the first case but the code of the second case shouldn't be executed in my opinion because the enum "EXACT_STRING_MATCHING" doesn'T match with "DEPTH_MATCHING".
If I put in a break statement after the first case it seem to be totally fine…
My code is the following:
[...]
MatchingMethods mM = currentMethod.getMatchMethod();
switch (currentMethod.getMatchMethod()) {
case EXACT_STRING_MATCHING:
//do something here
case DEPTH_MATCHING:
comparedNodePair.setDepthMatchResult(currentMetricResult);
break;
[...]
I am totally confused…
May someone be able to help me?
You already mentioned it, you have no break - switch works like goto where the case are labels to be jumped at and no "boundaries" or functions.
This is also the biggest critique concerning switch, because no one would use goto today, but switch which is certainly similar.
But it gets executed, because once one of the case satements is true the flow of execution "falls trough" see here for some information
this is normal if there is no break statement at the end of the case block.
add the break statement is necessary if you only want the exact block to be executed.