Go back to the parent if - java

I have this kind of code
if(a == 3) {
if(b == 4) {
// do somthing
} else {
// do an other thing
}
} else {
// do the same other thing
}
I wondered, when I am in the first else, how could I go to the second elsebecause it will execute the same code
Thank you

You only want the // do something part to be executed when a==3 AND b==4, so you can combine them with an && operator.
This way you can merge the two conditions into one, and have a single else clause that performs the // do an other thing part :
if(a == 3 && b == 4) {
// do something
} else {
// do an other thing
}

Related

How to refactor this Java snippet

For some reason, I can't help but see redundancy in this chunk of code. Can anybody help me refactor it be more readable and concise?
if (cachedParty == null || !cachedParty.equals(partyDto)) {
if (cachedParty == null
&& partyDto.getSellerStatusCode()
.equalsIgnoreCase(SellerStatusEnum.ACTIVE.getCode()))
{
pricingControlList.add(convertPartyDtoToPricingControl(partyDto));
} else if (!cachedParty.equals(partyDto)
&& cachedParty.getSellerStatusCode()
.equalsIgnoreCase(SellerStatusEnum.ACTIVE.getCode())
&& !partyDto.getSellerStatusCode()
.equalsIgnoreCase(SellerStatusEnum.ACTIVE.getCode())
) {
pricingControlList.add(convertPartyDtoToPricingControl(partyDto));
}
partyCache.put(partyDto.getSellerServicerNumber(), partyDto);
partiesToSaveOrUpdate.add(partyDto);
}
The comparison to SellerStatusEnum.ACTIVE may be implemented as a function accepting a Supplier<String>
Top level comparison may be simplified to remove cachedParty == null - it is assumed from the code that partyDto is not null and therefore it is enough to check !partyDto.equals(cachedParty)
An example implementation:
Function<Supplier<String>, Boolean> active = x -> SellerStatusEnum.ACTIVE.getCode().equalsIgnoreCase(x.get());
if (!partyDto.equals(cachedParty)) {
boolean partyActive = active.apply(partyDto::getSellerStatusCode);
if (null == cachedParty && partyActive
|| null != cachedParty && !partyActive && active.apply(cachedParty::getSellerStatusCode)
) {
pricingControlList.add(convertPartyDtoToPricingControl(partyDto));
}
partyCache.put(partyDto.getSellerServicerNumber(), partyDto);
partiesToSaveOrUpdate.add(partyDto);
}
I would suggest making helper method isActive(party) which returns partyDto.getSellerStatusCode().equalsIgnoreCase(SellerStatusEnum.ACTIVE.getCode(). Additionaly, there is a possible NPE when cachedParty == null because !cachedParty.equals(partyDto) is calling equals for null. So, considering that partyDto is never null, this can be reduced to !partyDto.equals(cachedParty).
Also, you're calling same method in if(x) else if (y) statement, so it can be reduced to one if statement with x or y check. So, let's rewrite your statement:
if (A or B) {
if ((A and C) or (B and D and !C)) { F() }
G()
}
As we decided in the first paragraph, A or B = B. So expression now looks like
if (B) {
if ((A and C) or (B and D and !C)) { F() }
G()
}
// and because inside first if statement B = true, we can remove B from nested if:
if (B) {
if ((A and C) or (D and !C)) { F() }
G()
}
So, by doing these optimisations we can get:
if (!partyDto.equals(cachedParty)) {
if (cachedParty == null && isActive(partyDto) || (isActive(cachedParty) && !isActive(partyDto)) {
pricingControlList.add(convertPartyDtoToPricingControl(partyDto));
}
partyCache.put(partyDto.getSellerServicerNumber(), partyDto);
partiesToSaveOrUpdate.add(partyDto);
}
I've noticed that there is no cachedParty != null check in your nested if, so final result will be look like this:
if (!partyDto.equals(cachedParty)) {
if (cachedParty == null && isActive(partyDto) || (cachedParty != null && isActive(cachedParty) && !isActive(partyDto)) {
pricingControlList.add(convertPartyDtoToPricingControl(partyDto));
}
partyCache.put(partyDto.getSellerServicerNumber(), partyDto);
partiesToSaveOrUpdate.add(partyDto);
}

how to remove from a list from a combo box

When trying to write the following code, it comes up with 3 errors. Syntax error on token 'else', insert 'assignmentoperator expression' to complete assignment and that cannot convert from string to boolean. This is for a combo box and when I choose from the combo box, I want to remove the other sites from a list. 'site' is a variable in main and c.site is a parameter in another agent. Can someone explain what to do.
if ( site ) {
if ( c.site.equals( "x" ) ) {
cavernIterator.remove();
continue;
}
}
else {
if ( c.site.equals( "y" ) ) {
cavernIterator.remove();
continue;
}
}
else {
if ( c.site.equals( "z" ) ) {
cavernIterator.remove();
continue;
}
}
else {
( c.site.equals( "a" ) ) {
cavernIterator.remove();
continue;
}
}
You can't have several else blocks for the same if. Each else block has to be attached to its own if:
if(a) {
...
} else {
if (b) {
...
}
else {
if (c) {
...
}
else {
...
}
}
}
Or, with a shorthand for all this, you can have a single-statement block inside the else, so it looks like this:
if (a) {
...
}
else if (b) {
...
}
else if (c) {
...
}
else {
...
}
This second one is nearly the same as the first, as it takes advantage of not having to wrap a statement block in braces if your statement block only has single statement, like this:
if (myCondition)
System.out.println("My condition passed");
else
System.out.println("My condition did not pass");
Else if should be written this way :
if (...) {
// Code here
} else if (...) {
// Code here
} else {
// Code here
}
Also your cases seem similar
String[] sites = {"x","y","z","a"};
boolean contains = Arrays.stream(sites).anyMatch(c.site::equals);
if (contains) {
cavernIterator.remove();
continue;
}
EDIT: Considering site is a string
String site = "x"; // Default value provided
String[] sites = {"x","y","z","a"};
boolean condition = site.equals(c.site) && Arrays.stream(sites).anyMatch(c.site::equals);
if (condition) {
cavernIterator.remove();
continue;
}
if ( site ) {
if ( c.site.equals( "x" ) ) {
}
}
equals
if(site && c.site.equals("x")){
}
And your last else is messed up.
Likely look on some Java tutorials because you write the least efficient way possible. This is your code in short:
if (site && (c.site.equals("x") || c.site.equals("y") || c.site.equals("z") || c.site.equals("a"))) {
cavernIterator.remove();
}

Refactoring empty if-statements

I currently working on a project that I need to remove a class that is being used by different other classes. There are cases that I can remove the one line of code that consists of that class where it will never affect the functionality of the program, but also there are cases that the class that you want to be removed is inside an if-statement. The main problem is that once I removed the line of code consisting of that class where is it inside the if-statement, it will be an empty if-statement that will violates the sonar.
Is there another way to refactor an empty if-statement other that negating the condition of one of the statements? Because when I'm just negating the condition, the readability of the code reduced.
For Example:
if((example_A >= 0) && (condition_A))
{
removeThisClass();
}
else if((example_B >= )) && (condition_B))
{
doSomething();
}
else
{
doAnything();
}
Refactored:
if(!((example_A >= 0) && (condition_A)) && ((example_B >= )) && (condition_B)))
{
doSomething();
}
else
{
doAnything();
}
You can put this code in separate method (https://refactoring.com/catalog/extractFunction.html) and write it like this:
public void DoSomeStuff() {
if((example_A >= 0) && (condition_A))
return;
if((example_B >= )) && (condition_B)) {
doSomething();
return;
}
doAnything();
}
If I understand you right, the line removeThisClass(); should be removed, and you don't want to be left with an empty block like this:
if((example_A >= 0) && (condition_A))
{
}
else if((example_B >= )) && (condition_B))
{
doSomething();
}
else
{
doAnything();
}
In order to not do the "A" tests twice, you need to negate the condition, e.g. like this:
if ((example_A < 0) || ! (condition_A))
{
if ((example_B >= )) && (condition_B))
{
doSomething();
}
else
{
doAnything();
}
}
Your refactored code is wrong, because if the "A" condition is true, the original code would execute removeThisClass();, which means it should now do nothing, but your code will call doAnything(); when "A" is true.
You can put in a comment. Sonar should accept that and it could also help the reader.
void doSomething() {
for (int i = 0; i < 42; i++) // Non-Compliant
{
}
for (int i = 0; i < 42; i++); // Compliant
if (myVar == 4) // Compliant - contains a comment
{
// Do nothing because of X and Y
}
else // Compliant
{
doSomething();
}
try // Non-Compliant
{
}
catch (Exception e) // Compliant
{
// Ignore
}
}

For loop to search through 2D array in Java returns NullPointerException

For a project at University, I have to create a game of Tic Tac Toe.
I have this for loop with if statements to search through the 2D array of 3x3 size, and return if it's either X or O (enum). That results in showing which side has won the game.
However, the problem I have is that if the 2D array is not complete, as in if all the 9 boxes are not filled with X or O, the method shows a NullPointerException.
Edit: I have to add that I require the empty grid to be null as few other unit tests assume grid[][] is initialized as null.
Error:
Exception in thread "main" java.lang.NullPointerException
at TicTacToeImplementation.whoHasWon(TicTacToeImplementation.java:80)
at ApplicationRunner.main(ApplicationRunner.java:24)
Code:
public enum Symbol {
X, O
}
private Symbol winner;
public Symbol whoHasWon() {
for (Symbol xORo : Symbol.values()) {
if ((grid[0][0].equals(xORo) &&
grid[0][1].equals(xORo) &&
grid[0][2].equals(xORo))) {
winner = xORo;
isGameOver = true;
break;
} else if ((grid[1][0].equals(xORo) &&
grid[1][1].equals(xORo) &&
grid[1][2].equals(xORo))) {
winner = xORo;
isGameOver = true;
break;}
else if { //Code carries on to account for all 8 different ways of winning
} else {
isGameOver = true;
}
}
return winner;
}
You can use multiple ways to ignore the "null" exception with an empty array.
The 1st way is to fill it with a different default symbol such as E. So when you initialize your arry at the beginning, instead of making it all empty and null, you can fill it with E's
for(int i=0;i<=2;i++){
for(int k=0;k<=2;k++){
grid[i][k] = "E";
}
}
Add this to beginning to fill it with E's first instead of nulls.
Another method is to find how to ignore the nulls using try or the following methods that can be found in this linkhttps://www.javacodegeeks.com/2012/06/avoid-null-pointer-exception-in-java.html:
I won't be going into it because I believe the 1st method is easier to use and implement. However, depending on your requirements for your assignment, I would look at both just to be sure.
Hope this helps, Good luck!
You can change the comparasion of String.The code may be like this ;
public Symbol whoHasWon() {
for (Symbol xORo : Symbol.values()) {
if ((grid[0][0] == xORo.name() &&
grid[0][1] == xORo.name() &&
grid[0][2] == xORo.name())) {
winner = xORo;
isGameOver = true;
break;
} else if ((grid[1][0] == xORo.name() &&
grid[1][1] == xORo.name() &&
grid[1][2] == xORo.name())) {
winner = xORo;
isGameOver = true;
break;}
else if { //Code carries on to account for all 8 different ways of winning
} else {
isGameOver = true;
}
}
return winner;
}
Enum like your's implemented
public enum Symbol{
X, O
}
}
As stated in this post, you can use either equals() or == to compare enums but using == is null safe while equals() isn't.
So basically, just write your checks like this:
if (grid[0][0] == xORo &&
grid[0][1] == xORo &&
// etc.
However, if you want to use the equals() method, you could just write a method that checks for null then compares the two values and returns the result:
public boolean isEqual(Symbol s1, Symbol s2) {
if (s1 != null && s1.equals(s2)) {
return true;
}
return false;
}
You could then call the isEqual() method like this:
if (isEqual(grid[0][0], xORo) &&
isEqual(grid[0][1], xORo) &&
// etc.

Questions on if and else statements

This is the question I saw on CodingBat:
Given 2 positive int values, return the larger value that is in the range 10..20 inclusive, or return 0 if neither is in that range.
And this is the code I have written:
public int max1020(int a, int b) {
if ( a>=10 && a<=20 && b>=10 && b<=20 && a>b)
return a;
if (a>=10 && a<=20 && b>=10 && b<=20 && b>a)
return b;
if (a>=10 && a<=20 && b<=10 || b>=20)
return a;
if (a<=10 || a>=20 && b>=10 && b<=20)
return b;
else return 0;
}
I am fairly confident that it is correct but still then I click run, the websites says that: max1020(9, 21) → 0 BUT my code returns 9. Can someone help me to check through my codes what is wrong with it? :)
public int max1020(int a, int b) {
if ( a>=10 && a<=20 && b>=10 && b<=20 && a>b)
return a;
if (a>=10 && a<=20 && b>=10 && b<=20 && b>a)
return b;
if ((a>=10 && a<=20) && (b<=10 || b>=20))
return a;
if ((a<=10 || a>=20) && (b>=10 && b<=20))
return b;
else return 0;
}
Adding brackets in 3rd and 4th line will fix the problem.
I suggest you change the if statements and use else if. It is just good coding practice to use else if statements instead of several if when possible.
Your code is breaking in the third if condition, where you have || b>=20. 3rd and 4th conditions should be more specific like below:
if (a>=10 && a<=20 && (b<=10 || b>=20))
return a;
if ((a<=10 || a>=20) && b>=10 && b<=20)
return b;
Adding these parentheses will do the trick.
i would prefer to assign the checks to a variable to have a more "readable" code. but this depends on personal preferences.
public int max1020(int a, int b) {
final boolean aInRange = a>=10 && a<=20;
final boolean bInRange = b>=10 && b<=20;
if (aInRange && bInRange) {
if (a > b) {
return a;
} else if (a < b) {
return b;
} else {
return 0;
}
} else if (aInRange) {
return a;
} else if (bInRange) {
return b;
} else {
return 0;
}
}
Of course Varun's answer is correct. Additionally, I'd like to elaborate on some comments, and show an alternative approach to the problem that's much simpler and less likely to contain mistakes.
While reading the problem statement, you may notice that the method is to return a value if some conditions are met, or return 0 otherwise. So you could initialize a result with the default value of 0, change the result if the conditions are met, then return the result. That would reduce the code to:
public int max1020(int a, int b) {
int result = 0;
if (a >= 10 && a <= 20) result = a;
if (b >= 10 && b <= 20 && b > result) result = b;
return result;
}
Can't make it much simpler, I'd think. (But if you can, please comment, I love KISS! :) )
This solution produces a slightly different result, if both a and b are in range and a=b, it will return a. The problem statement is not really clear if this should happen, as also shown by the comments to Varun's answer. Coincidentally (or not) Codingbat doesn't check that condition. The proposed solution on the site also returns a in this case.
If you think it should return 0 when a=b, it's quite easy to adjust,
public int max1020(int a, int b) {
int result = 0;
if (a != b) {
if (a >= 10 && a <= 20) result = a;
if (b >= 10 && b <= 20 && b > result) result = b;
}
return result;
}
Still pretty simple :)
To explain TJCrowder's comment about indentation: If you put the body of the if statement on the next line, you should use curly braces and indent the line. Otherwise, it's far too easy to misread it, or make a mistake when you change the code.
// this can be error prone and harder to read,
// especially if you have multiple if statements,
// or add a statement to the body of the if statement in the future
// (shouldn't do this)
if (condition)
statement;
// Personally I think this is totally fine for a simple statement.
// But I know not everybody will agree
if (condition) statement;
// Usually, you'll see this formatting.
// Even without reading anything, the formatting makes it instantly clear
// which statements belong to the body of the if
if (condition) {
statement;
}
Side note: the else statement in your code belongs only to the last if. Your formatting could make that clear by not putting an empty line between those, e.g.
if (condition) statement;
else statement;
if (condition) {
statement;
} else {
statement;
}
In your code the else statement is actually obsolete, you could simply return 0; on the last line.
Varun's suggestion that you could use else ifs is correct. Theoretically, if the condition of the first if statement is true, using else if would make the code skip the tests for the other ifs and be a little more efficient. Additionally, it'd show that subsequent if statements are only reached if the previous if statements were false.
Practically however, in your code it doesn't really matter, because the method will finish and return a value if the condition is true, and subsequent if statements will never be reached anyway.

Categories