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
}
}
Related
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();
}
public boolean Winner() {
for (int z = 0; z < 3; z++) {
if (board[z] != null && board[z] == board[z+3] && board[z] == board[z+6]
) {
return true;
}
}
for(int i=0; i<7;i+=3){
if (board[i] != null && board[i] == board[i+1] && board[i] == board[i+2]) {
return true;}
}
}
It returns me this error: this method must return a result of type boolean. What am I doing wrong?
Right now, the function isn't guaranteed to return a boolean, because it's possible that neither of the if statements will ever be entered.
You could fix it like this (but only do this if it's actually what your logic needs!):
public boolean Winner() {
for (int z = 0; z < 3; z++) {
if (board[z] != null && board[z] == board[z+3] && board[z] == board[z+6]
) {
return true;
}
}
for(int i=0; i<7;i+=3){
if (board[i] != null && board[i] == board[i+1] && board[i] == board[i+2]) {
return true;}
}
return false;
}
The Java compiler doesn't make assumptions that a for loop will have an iteration or that an if statement block will run.
There are execution paths where there is no return statement. What happens if the execution path doesn't execute any of the existing return statements and drops to the bottom? There isn't a return there.
Add a return at the bottom.
All possible ways that the method can exit need to return something. If your code makes it through both for loops without having an if condition evaluate to true, then you need a return at the end that specifies what gets returned.
The compiler is not aware that at least one of the loops will be executed. It takes into account all the possibilities of the execution and one of them is that neither of the loops will be executed and in that case there is no return statement. So insert a return statement out of the loops as well.
The answer to this question is easy. It happened to me too. The problem in your code is that you don't say to the computer what to do in case that the "if" statement is wrong, so you just have to add an "else {return false}" to every "if". Another tip is: please make your code cleaner and readable.
public boolean Winner() {
for (int z = 0; z < 3; z++) {
if (board[z] != null && board[z] == board[z+3] && board[z] == board[z+6]) {
return true;
} else {
return false;
}
}
for (int i=0; i<7; i+=3) {
if (board[i] != null && board[i] == board[i+1] && board[i] == board[i+2]) {
return true;
} else {
return false;
}
}
}
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
}
I'm getting a PMD warning UseCollectionIsEmpty and the exact message it gives is:
Substitute calls to size() == 0 (or size() != 0, size() > 0, size() <
1) with calls to isEmpty()
on the last else if statement.
My issue is that my statement is checking if my ArrayList is NOT empty. But the PMD warning is telling me to change it to isEmpty(), which is not what I need to do. What's the work around to fix this?
if (theNeighbors.get(getDirection()) == Terrain.CROSSWALK) {
myDirection = getDirection();
} else if (theNeighbors.get(getDirection().left()) == Terrain.CROSSWALK) {
myDirection = getDirection().left();
} else if (theNeighbors.get(getDirection().right()) == Terrain.CROSSWALK) {
myDirection = getDirection().right();
} else if (myPossDir.size() > 0) {
myDirection = myPossDir.get(random.nextInt(myPossDir.size()));
} else {
myDirection = getDirection().reverse();
}
Instead of
} else if (myPossDir.size() > 0) {
myDirection = myPossDir.get(random.nextInt(myPossDir.size()));
} else {
myDirection = getDirection().reverse();
}
You should use:
} else if (myPossDir.isEmpty()) {
myDirection = getDirection().reverse();
} else {
myDirection = myPossDir.get(random.nextInt(myPossDir.size()));
}
This will make the above PMD warning go away, and it more clearly states your intent, you want to check that the collection is not empty. Using size() is for other cases - when you don't compare it to zero.
EDIT: Changed order of ifs, so now you use isEmpty() instead of !isEmpty() (another PMD warning, and negated ifs are not as easily readable as not negated ones)
Instead of;
if ( myCollection.size() > 0)
you can use
if(myCollection !=null && !mycollection.isEmpty())
to fix this PMD error.
I am working on a project for my Intro to Java course. I submitted my code and the reviewer said I needed to rewrite the following:
public void move()
{
if (iCanWin() > -1)
{
moveOnColumn(iCanWin());
}
else if (theyCanWin(0, 0, false) > -1)
{
moveOnColumn(theyCanWin(0, 0, false));
else
{
moveOnColumn(brilliantMove());
}
}
int nextMove = iCanWin();
if(nextMove > -1) {
moveOnColumn(nextMove);
} else ...
Not sure what should come after the else... The reviewer said that this would avoid the repetitive calling of the same method.
generally in statement if-ifelse-else
if (check a condition is true?)
{
moveOnColumn(iCanWin()); //do something
}
else if (other condition is true?)
{
moveOnColumn(theyCanWin(0, 0, false)); //do something
else//otherwise
{
moveOnColumn(brilliantMove()); //if previous condition doesn't be true
almost one of them this line go to be execute
}
Just remove the repetitive calls where possible as #ajb mentioned
public void move(){
int nextMove = iCanWin();
if (nextMove <= -1){
nextMove = theyCanWin(0, 0, false);
if(nextMove <= -1){
nextMove = brilliantMove();
}
}
moveOnColumn(nextMove);
}