Breaking out of nested if - java

I have a bit of code that contains nested if statements:
if(numberOfNeighbors == 1){
//go through comparison again, add Pixel(i,j) to current linked list -> complist[numberOfComponents]
// break out of large check ??
if(ji.getPixelColor(i, j) == (ji.getPixelColor(i-1,j-1))){ //compare to top left
complist[numberOfComponents].addFirst(new Pixel(i,j,numberOfComponents)); break;
}
if(ji.getPixelColor(i, j) == (ji.getPixelColor(i,j-1))){ // compare to top
complist[numberOfComponents].addFirst(new Pixel(i,j,numberOfComponents)); break;
}
if(ji.getPixelColor(i, j) == (ji.getPixelColor(i+1,j-1))){ // compare to top right
complist[numberOfComponents].addFirst(new Pixel(i,j,numberOfComponents)); break;
}
if(ji.getPixelColor(i, j) == (ji.getPixelColor(i-1,j))){ // compare to left
complist[numberOfComponents].addFirst(new Pixel(i,j,numberOfComponents)); break;
}
} // end of if(numberOfNeighbors == 1)
Basically what I would like to do, however inefficient this may be, is compare a something 4 times, but if it turns out it is a match, break out of the set of the 4 nested if statements, as well as the outer if statement.
Will this work? or will it just break out of the nested if its currently at and continue to the next until its gone through all 4?

IMPORTANT: break statements are used to come out of loops but not branches
I understood your question but use break statement to go out of loops like for, while, do while. You can go out of if statement when the condition is satisfied and statements inside the if branch are executed. If you don't want to check for other conditions when your first if is satisfied you have to use if else branches instead of using 4 if statements.
These two links might be useful
if else document
break document
See the below example
if(condition) {
if(condition) { //if this evaluates to true, logic1 is executed
logic1;
}
else if(condition) { //if the above condition fails, but this condition satisfies then logic 2 is executed
logic2;
}
else { //if the above 2 conditions fail, you can execute logic3
logic3;
}
}

Are you looking for else?
if(numberOfNeighbors == 1){
//go through comparison again, add Pixel(i,j) to current linked list -> complist[numberOfComponents]
// break out of large check ??
if(ji.getPixelColor(i, j) == (ji.getPixelColor(i-1,j-1))){ //compare to top left
complist[numberOfComponents].addFirst(new Pixel(i,j,numberOfComponents)); break;
}
else if(ji.getPixelColor(i, j) == (ji.getPixelColor(i,j-1))){ // compare to top
complist[numberOfComponents].addFirst(new Pixel(i,j,numberOfComponents)); break;
}
else if(ji.getPixelColor(i, j) == (ji.getPixelColor(i+1,j-1))){ // compare to top right
complist[numberOfComponents].addFirst(new Pixel(i,j,numberOfComponents)); break;
}
else if(ji.getPixelColor(i, j) == (ji.getPixelColor(i-1,j))){ // compare to left
complist[numberOfComponents].addFirst(new Pixel(i,j,numberOfComponents)); break;
}
} // end of if(numberOfNeighbors == 1)

break; does NOT work for if statements, only loops, switch and such.
You can do this to avoid nesting:
if(mainCondition)
{
if(condition1)
goto LabelContinue;
bool condition2 = logic...;
if(condition2)
goto LabelContinue;
//Code
}
LabelContinue:
//Other code.

Related

Java 8, While Loop: Reduce the total number of break and continue statements in this loop to use at most one

I've got a class which contains the following:
while (true) {
// if minimum element in the queue is greater than required sweetness
// then we are done
if (queue.peek() >= minSweetness) {
solutionPossible = true;
break;
} else {
// if there are more than or equal to 2 elements,
// then only solution is possible
// because we have already checked queue.peek() for the single element
// present, and that is less than minSweetness
if (queue.size() >= 2) {
// remove minimum and 2nd minimum values
int a1 = queue.poll();
int a2 = queue.poll();
// again push the value to the queue
// after calculating the combined sweetness
queue.offer(a1 + 2 * a2);
} else {
// for single element that is less than required sweetness
// no solution is possible
solutionPossible = false;
break;
}
// increase total number of operations
operations++;
}
}
Here is a screenshot:
VScode tells me to reduce the total number of break and continue statements in this loop to use at most one,
so I am not as experienced as to what other method I can think of, I tried to used quick fix and It didn't work,
anybody has any idea how to write this class differently...?
I tried to use quick fix and it didn't show other options though...
Assuming you need to preserve the original structure of the loop (i.e. while (true) ) then this is one method of complexity reduction (comments removed):
while (true)
{
if (queue.peek() >= minSweetness || queue.size() < 2) {
solutionPossible = (queue.peek() >= minSweetness);
break;
}
int a1 = queue.poll();
int a2 = queue.poll();
queue.offer(a1 + 2 * a2);
operations++;
}
The two loop "breaks" are condensed into one. The difference in their processing is the setting of the solutionPossible which can be set based on the first condition.
The else is removed as unnecessary.
If peek were a costly operation (which it likely is not) then assigning the result to variable first would be an optimization since it is used twice.
Instead of coding the while as an infinite loop, and breaking out of it, use a variable to control loop continuation or exit. In this case, I chose a boolean:
boolean decided = false;
while ( ! decided ) {
// if a minimum element in the queue is
// greater than the required sweetness
// then we are done
if (queue.peek() >= minSweetness) {
solutionPossible = true;
decided = true;
} else {
// if there are more than or equal to 2 elements,
// then only solution is possible
// because we have already checked
// queue.peek() for the single element
// present, and that is less than minSweetness
if (queue.size() >= 2) {
// remove minimum and 2nd minimum values
int a1 = queue.poll();
int a2 = queue.poll();
// again push the value to the queue
// after calculating the combined sweetness
queue.offer(a1 + 2 * a2);
} else {
// for a single element that is
// less than the required sweetness
// no solution is possible
solutionPossible = false;
decided = true;
}
// increase the total number of operations
operations++;
}
}
By the way, I like retaining the first break. It's a style preference:
boolean decided = false;
while ( ! decided ) {
// if a minimum element in the queue is
// greater than the required sweetness
// then we are done
if (queue.peek() >= minSweetness) {
solutionPossible = true;
decided = true;
break;
// if there are more than or equal to 2 elements,
// then only solution is possible
// because we have already checked
// queue.peek() for the single element
// present, and that is less than minSweetness
if (queue.size() >= 2) {
...
Retaining the first break allows elimination of the first else, reducing the nesting level by one for the code that follows.

How to solve errors in If statements

When I try a nested if function, it only outputs the "else" part.Like in the code below. what can I do?
if (B==1)
{
Classmate();
}
if (B==2)
{
results()
} else
{
JOptionPane.showInputDialog(null,"Invalid choice");
I am assuming in your code, your if (b == 2) conditional was meant to be nested.
Your { } brackets are not lined up properly. In order for a conditional if to be nested, it must be INSIDE of the other brackets.
Based on that assumption...
A nested conditional if (b == 2) will only run IF the first conditional is true (i.e. if (b == 1) ).
So to sum things up, if and only if (b == 1), it will check if (b == 2). if (b != 1), then the else will run.
Hopefully that helps. Also look into styling guides on formatting lines. It will make your life easier in the long run. :)
if (B==1) {
Classmate();
if (B==2){
results()
}
}
else {
JOptionPane.showInputDialog(null,"Invalid choice");
}

Wrap Around Grid - errors on east/west only

I have four methods that check whether or not a given grid location is next to an occupied location (value of 1). The grid is assumed to wrap around, ie, if in a 50x50 grid[0][1] is the given location and grid[49][1] is occupied, the method should return true/ My checkNorth and checkEast method are working fine, but I get an ArrayIndexOutofBoundsException: -1 error for either the south or west methods every time I run the program. I checked my math and I think it should work - am I using the modulo incorrectly, or am I missing something else?
EDIT: Clarified the wrapping criterion, word use correction.
boolean checkWest(int indexA, int indexB)
{
if (indexA-1 > 0)
{
if (grid[indexA-1][indexB] == 1)
{
return true;
}
}
if (indexA-1 < 0)
{
if (grid[(indexA-1)%width][indexB] == 1)
{return true;}
else return false;
}
return false;
}
I see a couple problems. First, Java arrays are zero-indexed, which means that the first element is at index 0. So it's okay to check grid[indexA-1][indexB] when indexA-1 is equal to 0. Second, you're not properly handling when indexA equals 0. Here is my implementation. I also simplified the logic a bit.
boolean checkWest(int indexA, int indexB)
{
if (indexA > 0)
return grid[indexA - 1][indexB] == 1;
else
return grid[width + indexA - 2][indexB] == 1;
}
EDIT: I'm pretty sure I butchered the math with the second return statement. It should be right now...

Java issue using parseInt with a try catch block

I am working on an exercise, where I have to select a category(genre) of movie and based on my selection, the program will return a list of movies in that category from an ArrayList of objects.
My program works when typing out a category in string format. However I am trying to use a try catch block to also allow category selection by number.
My catch block is working, however my try block is not and returns nothing. Can someone help me determine what is wrong with my code? I am guessing there is something wrong with my parseInt assignment?
System.out.print("What category are you interested in?");
String catSel = sc.next();
try //Check category for Integer, otherwise catch
{
int numSel = Integer.parseInt(catSel);
if(numSel == 1)
{catSel = "animated" ;}
if(numSel == 2)
{catSel = "drama";}
if(numSel == 3)
{catSel = "horror";}
if(numSel == 4)
{catSel = "scifi";}
if(numSel == 5)
{catSel = "musical";}
if(numSel == 6)
{catSel = "comedy";}
else catSel = "";
//Check each movie for chosen category
for(int x = 0; x < list.size() - 1; x++)
{
if(catSel.equals(list.get(x).category))
System.out.println(list.get(x).movie);
}
}
catch (NumberFormatException e)
{
//Check each movie for chosen category
for(int x = 0; x < list.size() - 1; x++)
{
if(catSel.equals(list.get(x).category))
System.out.println(list.get(x).movie);
}
}
the way your if-clauses are structured, the else clause will be called whenever numSel is not 6, replacing catSel with the empty string.
You may want to add an else after each if block or replace all of them with a switch statement.
As #Dragondraikk suggested your if-else clauses are structured in a way which is not as per your expected result .
So either use in this way :
if(someCondition){
}
else if(someCondition){
}
...........................
do whatever you want to do
...........................
else{
}
Below is the way to use Switch Statement
switch(Integer.parseInt(catSel)){
case 1 :
do Something....
break;
case 2 :
do Something....
break;
case 3 :
do Something....
break;
case 4 :
do Something....
break;
case 5 :
do Something....
break;
case 6 :
do Something....
break;
default :
catSel="";
break;
}
Note : You can use try-catch block around this
Update
Advantage of Using Switch over If else
The problem with the if...else if... chain is readability , I have to look at every single if condition to understand what the program is doing. For example, you might have something like this:
if (a == 1) {
// stuff
} else if (a == 2) {
// stuff
} else if (a == 3) {
// stuff
} else if (b == 1) {
// stuff
} else if (b == 2) {
// stuff
}
(obviously, for a small number of statements like this, it's not so bad)
but I'd have no way of knowing that you changed condition variable half-way through without reading every single statement. However, because a switch limits you to a single condition variable only, I can see at a glance what's happening.
Another advantage is JumpTable
A switch is often compiled to a jump-table (one comparison to find out which code to run), or if that is not possible, the compiler may still reorder the comparisons, so as to perform a binary search among the values (log N comparisons). An if-else chain is a linear search .
Here is more about Switch Statement

How to execute code based on integer value

I have an int, int minion1Hp, which can be a value of 0 -> 20. Depending on the value it is, a certain image resource will be set for an ImageView, using bar1.setImageResource(R.drawable.hpa);. However, my code currently looks like this:
if (minion1Hp == 0) {
bar1.setImageResource(R.drawable.hp);
}
if (minion1Hp == 1) {
bar1.setImageResource(R.drawable.hpa);
}
if (minion1Hp == 2) {
bar1.setImageResource(R.drawable.hpb);
}
if (minion1Hp == 3) {
bar1.setImageResource(R.drawable.hpc);
}
if (minion1Hp == 4) {
bar1.setImageResource(R.drawable.hpd);
}
if (minion1Hp == 5) {
bar1.setImageResource(R.drawable.hpe);
}
... and so on. Is there a more efficient way of doing this, rather than a long list of if statements?
Suggestion: initialize a map at startup (say in onCreate()). Like this:
mDrawables = new HashMap<Integer, Integer>();
mDrawables.put(0, R.drawable.hp);
mDrawables.put(1, R.drawable.hpa);
...
then just do:
bar1.setImageResource(mDrawables.get(minion1Hp));
You can use a switch statement with a separate case for each instance. On a side note, you shouldn't be using just if statements up there, your code will run slowly, you should be using else if to make it run faster (since your hp can never be 1 and 2 at the same time.
Ex for switch statements:
switch (minion1Hp){
case 1:
bar1.setImageResource(R.drawable.hp);
break;
case 2:
bar1.setImageResource(R.drawable.hpa);
break;
etc.
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html
An improvement here would be to change each if after the first one to an else if as minion1Hp can't be multiple values at the same time, but you might find it slightly neater to have the whole thing in a switch-case block instead.

Categories