Switch Statement: Execute Code Once - java

If I have a switch statement testing the value of integer i, how can I execute the same code once?
For example:
switch(i) {
case 0:
if(j == 2) {
booleanA = true;
booleanB = false;
case 1:
if(j == 4) {
booleanA = true;
booleanB = false;
}
With 5 different cases, instead of me having to type out
booleanA = true;
booleanB = false;
five times, is there a way to say if one of the if statements is true, use this block of code? Is that possible?
Thanks!

You can do it without a switch statement...
int[] requiredJ = {2,4};
if (j == requiredJ[i]) {
booleanA = true;
booleanB = false;
}

I can not understand logic behind your code, but may be this can be done ( Like switch hit in cricket !!! :p).
Assign the values to your booleans, and revert in default case.
booleanA = true;
booleanB = false;
// more code blocks
switch(i) {
case 0:
// Process
break;
case 1:
// Process
break;
default :
booleanA = false;
booleanB = true;
}

Related

Why isn't .equals recognizing my variable as the same string that I'm passing it?

So this little function is supposed to check if parentheses and brackets are matched next to each other. I feel like it should work and I've tried it a few different ways but I can't figure out how to check if my next char is what I expect it to be.
class Parenths {
public boolean isValid(String s) {
char[] parens = s.toCharArray();
if (parens.length == 0) return true;
for (int i = 0; i < parens.length; i+=2) {
String curr= String.valueOf(parens[i]);
String next = String.valueOf(parens[i+1]);
// System.out.println(next.equals(")"); --------> false
// System.out.println(Object.equals(next, ")")); ----> error
switch (curr) {
case "(": if (!next.equals(")")) return false;
case "{": if (!next.equals("}")) return false;
case "[": if (!next.equals("]")) return false;
}
}
return true;
}
}
You can see the lines I printed to debug and it seems that .equals is not the right thing to use here? Can anyone explain why this isn't working?
PS. I realize I don't have to convert the string to a char array to compare elements, so unless that's the only fix, please don't point that out to me.
Not tested, but it seems to be a problem of fall through. Try to replace if (boolean) return boolean with return boolean, this should do the trick.
The problem is that you don't have a break at the end of the cases, so if, for example, your first case is true, it will not stop execution and execute the 2nd test, which will be false. If you change your conditional statements to a direct return, you will not have this problem.
EDIT: Sorry, I read too quickly. Doing so will break your loop. Actually, you have to add a break at the end of the cases.
case "(": if (!next.equals(")")) return false; break;
case "{": if (!next.equals("}")) return false; break;
case "[": if (!next.equals("]")) return false; break;
First , you have to add break; after the cases its important to stop seeing the cases
switch (curr) {
case "(": if (!next.equals(")")) return false;
break;
case "{": if (!next.equals("}")) return false;
break;
case "[": if (!next.equals("]")) return false;
break;
}
Secondly , your code doesnt support the confrotation of a closing patenthesis at first , you have to add a default case
switch (curr) {
case "(": if (!next.equals(")")) return false;
break;
case "{": if (!next.equals("}")) return false;
break;
case "[": if (!next.equals("]")) return false;
break;
default :
break;
}
return true;
Also , you have to make sure the next element is not null before comparing to it , and dont increment with 2 , you give a String with a one element and that's why you get the error
public static boolean isValid(String s) {
char[] parens = s.toCharArray();
if (parens.length == 0) return true;
for (int i = 0; i < parens.length; i++) {
String curr= String.valueOf(parens[i]);
String next = "";
try {
next = String.valueOf(parens[i+1]);
switch (curr) {
case "(": if (!next.equals(")")) return false;
break;
case "{": if (!next.equals("}")) return false;
break;
case "[": if (!next.equals("]")) return false;
break;
default :
break;
}
return true;
}catch(Exception e) {}
}
return false;
}
Test :
System.out.println(isValid("()"));
// Output : true
System.out.println(isValid("("));
// Output : false

Java, class, Boolean, logic mess

So, we were given to code this ScantronGrader for homework, and the specs say that we have to create this class isValid to check to validity of the options that fall into either A, B, C, or D (all uppercase), I first tried switch (error), if-else-if (error); do-while (Oh, I know so wrong and error). I tried for loop first, and the value didn't get incremented.
In its recent rendition, this is my issue. TBH, I don't even know what I am doing anymore.
public static boolean isValid(String inputstr)
{
int x = 0;
do
{
switch (inputstr.charAt(x))
{
case 'A':
case 'B':
case 'C':
case 'D':
return true;
default: return false;
x++;
}
} while (x < inputstr.length());
}
}
The problem with this is that it is not letting me increment the counter. Now, I need to do that, else, how would I shift right? Either way, please HALP.
Not sure if i understood what that method have to do, but if it has to return true only if the string have those letter you can do this:
public static boolean isValid(String inputstr)
{
int x = 0;
boolean bool = true;
do
{
if(!(inputstr.charAt(x) == 'A' || inputstr.charAt(x) == 'B' || inputstr.charAt(x) == 'C' || inputstr.charAt(x) == 'D'))
{
bool = false;
}
x++;
}while (x < inputstr.length());
return bool;
}
Okay, so after some ideas from here (Thank you for reaching out to help), I am toying with this one which seems to work. Just let me know if I am doing anything unnecessary/ useless, or there is a more efficient way to do this, please?
public static boolean isValid(String inputstr) {
int count = 0;
for (int x = 0; x < inputstr.length(); x++) {
switch (inputstr.charAt(x)) {
case 'A':
case 'B':
case 'C':
case 'D':
break;
default: count++;
}
}
if (count == 0) {
return true;
}
else {
return false;
}
}

Repetitive if statements reduction

What are the ways of reducing code quantity in a method that contains schematic conditional statements?
What would be a good practice of placing such code. Should it be in a different method/class?
Example code in Java. It contains one scheme repeated twice:
if (calculation[i].equals("*")) {
if (stack.canDoOperation()) {
times();
} else {
operationFailed = true;
}
} else if (calculation[i].equals("+")) {
if (stack.canDoOperation()) {
sum();
} else {
operationFailed = true;
}
}
You could write a helper method, wrapping the given operation method into the commonly required checks. You could also put a try/catch in there, in case the operation can fail.
private boolean tryOperation(Runnable operation) {
if (stack.canDoOperation()) {
operation.run();
return true;
} else {
return false;
}
}
And use like this:
if (calculation[i].equals("*")) {
operationFailed = ! tryOperation(this::times);
} else if (calculation[i].equals("+")) {
operationFailed = ! tryOperation(this::sum);
}
Or, with Java 8, you can put the method references to those operations into a Map:
Map<String, Runnable> operations = new HashMap<>();
operations.put("*", this::times);
operations.put("+", this::sum);
...
Runnable operation = operations.get(calculation[i]);
if (operation != null && stack.canDoOperation()) {
operation.run();
} else {
operationFailed = true;
}
You can also combine the two approaches:
operationFailed = ! tryOperation(operations.get(calculation[i]);
Here is some example of how you can utilize repetitive statements. For more clarity you can extract stack.canDoOperation() to variable if it doesn't break your logic. Also you can consider moving it to assertion in beginning of the method and than put calculation[i] into switch statement.
if (calculation[i].equals("*") && stack.canDoOperation()) {
times();
}
} else if (calculation[i].equals("+") && stack.canDoOperation()) {
sum();
}
} else {
operationFailed = true;
}
You can use a switch statement into an if and maybe in a more logical way : check if you can do an operation, and if so find which one :
if (stack.canDoOperation()) {
switch(calculation[i]){
case "*": times(); break;
case "+": sum(); break;
} else {
operationFailed = true;
}
You can also give the value of operationFailed into the if statement :
operationFailed = !stack.canDoOperation() will be done first (if you cannot do an operation, operationFailed will true;
the value of !operationFailed (!!stack.canDoOperation() = stack.canDoOperation()) will be used in the if test
if (!(operationFailed = !stack.canDoOperation())) {
switch(calculation[i]){
case "*": times(); break;
case "+": sum(); break;
}
Since Java 7, it's possible to switch over Strings.
switch (calculation[i]) {
case "*":
times();
break;
case "+":
sum();
break;
}
Furthermore, for each calculation type, you are repeating the canDoOperation check. It's better that you bubble up this check:
if (stack.canDoOperation()) {
operationFailed = true;
}
else {
switch ... // Your switch statement
}
I suggest you move these operations to a separate method:
/**
* Performs the specified operation.
* #param The operation to perform.
* #return True if the operation was succeeded, false otherwise.
*/
boolean performOperation(String operation) {
if (!stack.canDoOperation()) {
return false;
}
switch (operation) {
case "*":
times();
break;
case "+":
sum();
break;
default:
return false;
}
return true;
}
However, without knowing the rest of your code, it's unclear whether this is a good solution.

convert multi if-else statements to be more functional

How does one make an if else statement functional
boolean condition1;
boolean condition2;
final Object a = new Object();
final Object b = new Object();
final Object c = new Object();
final Object d = new Object();
if (condition1 && condition2) {
return a;
}
else if (condition1 && !condition2) {
return b;
}
else if (!condition1 && condition2) {
return c;
}
else {
return d;
}
I would like to know how can one refactor this type of conditional statements to be more functional, with no overhead in performance preferbly.
I was thinking of Mapping predicates to the object, would this be an approach?
I've added 2 more conditions to spice it up a bit. The if/else statements can get pretty in-depth, so you can use bit-wise to clarify things and merge the conditions. To me, this clarifies the code - cause it's one level deep, no matter how many conditions.
final int BIT_CONDITION_1 = 0x01;
final int BIT_CONDITION_2 = 0x02;
final int BIT_CONDITION_3 = 0x04;
final int BIT_CONDITION_4 = 0x08;
boolean condition1 = false;
boolean condition2 = false;
boolean condition3 = false;
boolean condition4 = false;
int mergedConditions = 0;
if (condition1)
mergedConditions |= BIT_CONDITION_1;
if (condition2)
mergedConditions |= BIT_CONDITION_2;
if (condition3)
mergedConditions |= BIT_CONDITION_3;
if (condition4)
mergedConditions |= BIT_CONDITION_4;
// continue as needed
// now you can check all conditions using the set bits.
switch(mergedConditions) {
case 0: // no bits set
System.out.println("No bits set");
break;
case 1:
System.out.println("Conditions set = 1");
break;
case 2:
System.out.println("Conditions set = 2");
break;
// You can also clarify case statements by using constants
case (BIT_CONDITION_1 | BIT_CONDITION_2):
System.out.println("Conditions set = 1,2");
break;
case 4:
System.out.println("Conditions set = 3");
break;
case 5:
System.out.println("Conditions set = 1,3");
break;
case 6:
System.out.println("Conditions set = 2,3");
break;
case 7:
System.out.println("Conditions set = 1,2,3");
break;
case 8:
System.out.println("Conditions set = 4");
break;
case 9:
System.out.println("Conditions set = 1,4");
break;
case 10:
System.out.println("Conditions set = 2,4");
break;
case 11:
System.out.println("Conditions set = 1,2,4");
break;
// etc ... Continue as needed
}
For two conditions there's nothing wrong with your if/then/else statements. If you have more conditions, there's a way to "simplify" the code using a truth table.
public Object method()
{
Object objects[] = { a, b, c, d }; // Assuming objects a, b, c and d exist...
boolean condition1;
boolean condition2;
/*
* Truth Table
*
* condtion1 condition2 Object
* false false d
* false true c
* true false b
* true true a
*/
int selector = (condition1 ? 0 : 1) + (condition2 ? 0 : 2);
return objects[selector];
}
Not sure if this is what you had in mind but it's a typical way to dispatch multiple conditions. While at first glance it looks arcane, if you document the entire truth table for all conditions it can be very safe, since it forces you to consider ALL possible combinations. This can really help when you have more than two conditions.

Indent all lines after a certain character until another character

For an assignment we are creating a java program that accepts a java file, fixes messy code and outputs to a new file.
We are to assume there is only one bracket { } per line and that each bracket occurs at the end of the line. If/else statements also use brackets.
I am currently having trouble finding a way to indent every line after an opening bracket until next closing bracket, then decreasing indent after closing bracket until the next opening bracket. We are also required to use the methods below:
Updated code a bit:
public static void processJavaFile() {
}
}
This algorithm should get you started. I left a few glitches that you'll have to fix.
(For example it doesn't indent your { brackets } as currently written, and it adds an extra newline for every semicolon)
The indentation is handled by a 'depth' counter which keeps track of how many 'tabs' to add.
Consider using a conditional for loop instead of a foreach if you want more control over each iteration. (I wrote this quick n' dirty just to give you an idea of how it might be done)
public String parse(String input) {
StringBuilder output = new StringBuilder();
int depth = 0;
boolean isNewLine = false;
boolean wasSpaced = false;
boolean isQuotes = false;
String tab = " ";
for (char c : input.toCharArray()) {
switch (c) {
case '{':
output.append(c + "\n");
depth++;
isNewLine = true;
break;
case '}':
output.append("\n" + c);
depth--;
isNewLine = true;
break;
case '\n':
isNewLine = true;
break;
case ';':
output.append(c);
isNewLine = true;
break;
case '\'':
case '"':
if (!isQuotes) {
isQuotes = true;
} else {
isQuotes = false;
}
output.append(c);
break;
default:
if (c == ' ') {
if (!isQuotes) {
if (!wasSpaced) {
wasSpaced = true;
output.append(c);
}
} else {
output.append(c);
}
} else {
wasSpaced = false;
output.append(c);
}
break;
}
if (isNewLine) {
output.append('\n');
for (int i = 0; i < depth; i++) {
output.append(tab);
}
isNewLine = false;
}
}
return output.toString();
}

Categories

Resources