I was implementing an N-nary tree (here N=4) and want to put in a logic to do something if the boolean property val of all four children of a node are equal, I tried with:
if (childOne.val == childTwo.val == childThree.val == childFour.val){
doSomthing();
}
however this doesn't work for my test cases, so I have to change it to a more explicit and verbose:
if (childOne.val == childTwo.val && childTwo.val == childThree.val && childThree.val == childFour.val){
doSomthing();
}
and this one works. However I cannot make sense why the first evaluation doesn't give me the correct answer.
The == operator is left associative, so your first expression looks like this with brackets added:
(((childOne.val == childTwo.val) == childThree.val) == childFour.val)
Here's a case where the above will be true, but not all four values are the same:
child 1 and 2 are false
child 3 and 4 are true
Another way of doing this:
Stream.of(childOne.val, childTwo.val, childThree.val, childFour.val)
.distinct().count() == 1
I suggest you stick with the plain old && because there isn't a BooleanStream and the booleans need to be boxed.
Related
I'm running my code on sonarqube, but it shows there's an issue with my code, saying"Merge this if statement with the enclosing one." I tried it, but still have no idea how to solve it.
if (splitStrings.length == 2) {
if (!splitStrings[1].matches("\\d{1,3}")
|| Integer.parseInt(splitStrings[1]) > 100
|| Integer.parseInt(splitStrings[1]) < 1) {
throw new IllegalArgumentException("Invalid Input");
}
}
You could do three things:
Either you need to chain the conditions as below:
if (splitStrings.length == 2
&& (!splitStrings[1].matches("\\d{1,3}")
|| Integer.parseInt(splitStrings[1]) > 100
|| Integer.parseInt(splitStrings[1]) < 1)) {
throw new IllegalArgumentException("Invalid Input");
}
You could declare local variable for Integer.parseInt(splitStrings[1]) inside the first if after adding the matches condition in it.
if (splitStrings.length == 2 && splitStrings[1].matches("\\d{1,3}")) {
int val = Integer.parseInt(splitStrings[1]);
if (val > 100 || val < 1)) {
throw new IllegalArgumentException("Invalid Input");
}
}
Even though i won't recommend it, you could also suppress the warning using //NOSONAR in the line in which warning is displayed or add #SuppressWarnings("squid:S1066") at the method level.
Try this.
if (splitStrings.length == 2
&& (!splitStrings[1].matches("\\d{1,3}")
|| Integer.parseInt(splitStrings[1]) > 100
|| Integer.parseInt(splitStrings[1]) < 1)) {
throw new IllegalArgumentException("Invalid Input");
}
You should merge them by && between them and wrap the second with brackets, like:
if(splitStrings.length == 2 && (!splitStrings[1].matches("\\d{1,3}") || Integer.parseInt(splitStrings[1]) > 100 || Integer.parseInt(splitStrings[1]) < 1)){
//code here
}
Integer.parseInt may be skipped altogether if a better regexp is provided to check for the digits in the range [1..100], thus the conditions could be simplified:
if (splitStrings.length == 2 && !splitStrings[1].matches("(?!0)\\d{1,2}|100")) {
throw new IllegalArgumentException("Invalid Input");
}
Online demo of the regexp: (?!0)\d{1,2}|100 validating positive cases 0 < x <= 100
(?!0)\d{1,2} - 1 or 2 digit numbers except 0 excluded with negative lookahead (?!0): 1 - 99
|100 - OR 100
In my opinion the assertion that combining if statements makes code more readable is flawed. Often it makes sense to ask a series of questions in sequence, especially when each part is asking an essentially independent question.
This can (in direct opposition of the SonarQube assertion) make each part more readable. It also allows for correct placement of useful comments in cases where the meaning is not stupidly obvious.
Another valid reason for nested if statements would be to follow certain easily recognized coding patterns. An example would be in ASP.Net applications where Page_Load methods may often have an if (!PostBack) block, which can then contain additional logic that may include additional nested conditions. If there is only one nested condition and it is combined, later changes may need to undo that merge. (There may be a case at that point for refactoring the logic into a separate method at that point, but that is a different subject.)
The question of whether or not to combine nested if statements should be left to the discretion and good judgement of the author (and code reviewer) based on which form is more readable and/or maintainable.
In your particular case, your logic is asking two questions: (1) "Does the input have two parts?" and (2) "Is the second part valid"?
So yes, your nested if statements can be combined into a single (but logically more complex) statement, but this is not necessarily better.
Another class is going to pass in random numbers into this method(x,y,z). I want to know the boolean that does returns true from my last if() statement, so I can do operations on it. I have explained my logic in the comments.
I am still really new to this, so my logic may be wrong.
public static String FindDate(int x, int y, int z) {
boolean istrue1 =(x >= 1 && x <= 31);
boolean istrue2 =(y >= 1 && y <= 31);
boolean istrue3 =(z >= 1 && z <= 31);
if(istrue1 ^ istrue2){
if(istrue1^istrue3){
if(istrue2^istrue3){//now knowing that no values are the same, i can find the true value.
if(istrue1||istrue2||istrue3){
// I want to store/use/print/know which bool(istrue) that evaluated to true, so I would know if it is
//x,y,z that went through the algorithm successfully.
}
} else{return "Ambiguous";}
}else{return "Ambiguous";}
}else{return "Ambiguous";}
return "true"; //I would actually end up returning the value that went through the algorithm
}
You can store boolean values just like any other type in Java. I'm not sure exactly what your last comment means by "the value that went through", but if you want to keep track of the result of a particular test, you don't necessarily need to write something like
if (a == b) {
return true;
} else {
return false;
}
In that case,
return a == b;
is equivalent. If the expression is more complicated parens are a good idea.
return ((a == b) || c);
And instead of returning, you could always store the result and do something with it later.
bool test = ((a == b) || c);
action(test);
You can your following: But your condition is incorrect 3 variable for two value (true, false) all can't be different. So your logic always return "Ambiguous"
if(istrue1 ^ istrue2){
if(istrue1^istrue3){
if(istrue2^istrue3){
//now knowing that no values are the same, i can find the true value.
if(istrue1||istrue2||istrue3){
// I want to store/use/print/know the bool that evaluated to true, so I would know if it is
//x,y,z that went through the algorithm successfully.
return "true";
}
}
return "Ambiguous";
Instead of:
if(istrue1||istrue2||istrue3)
Its is easiest to just break it down into 3 differnt if statement.
if(istrue1)
if(istrue2)
if(istrue3)
No easy trick that i was hoping for. sad day.
Also the statements i did with the xor(^) operators turns out to be bad logic.
it would be easiest to this:
if(a&&b || a&&c || b&&c)
That would return ambiguous if any combo are both true.
However thats not the original question, but I thought i might as well mention it.
In my quiz game on the very end of a level I have to check some conditions, 4 of them. During the game I add +1 to an integer variable, 4 variables. On the end of the level I sum these values to another integer, activeButtonsTotal. And I set 4 boolean values to true or false. So, I need to check 2 conditions four times: if it's my boolean is false AND if my activeButtonsTotal is equal to 16 and if it is to set one of my buttons to Enabled, and this same thing for the next boolean and activeButtonsTotal, and 4 times like this. I need to go through all 4 of them. I tried with if statements, and else if but no luck.
boolean columnACorrecct, columnBCorrect, columnCCorrect, columnDCorrect;
activeButtonsTotal = activeButtonsA+activeButtonsB+activeButtonsC+activeButtonsD;
if((columnACorrect=false) && (activeButtonsTotal==16)){
columnA.setEnabled(true);
}
if((columnBCorrect=false) && (activeButtonsTotal==16)){
columnB.setEnabled(true);
}
if((columnCCorrect=false) && (activeButtonsTotal==16)){
columnC.setEnabled(true);
}
if((columnDCorrect=false) && (activeButtonsTotal==16)){
columnD.setEnabled(true);
}
im not sure that i follow all your logic, but your "if" statements all are missing an equal sign. You said you have to compare if your boolean is false, AND the number, but you are assigning "False" inside the condition. you need "==".
I would do:
if(activeButtonsTotal==16)
{
columnA.setEnabled(!columnACorrect);
columnB.setEnabled(!columnBCorrect);
columnC.setEnabled(!columnCCorrect);
columnD.setEnabled(!columnDCorrect);
}
I would do something like that:
columnA.setEnabled(!columnACorrect && activeButtonsTotal==16);
columnB.setEnabled(!columnBCorrect && activeButtonsTotal==16);
columnC.setEnabled(!columnCCorrect && activeButtonsTotal==16);
columnD.setEnabled(!columnDCorrect && activeButtonsTotal==16);
You are assigning your boolean variable to false every time you try to check a condition.
This will result in the condition to be false and will never run the code within the block.
To check for equality, use ==;
columnACorrect==false
columnBCorrect==false
columnCCorrect==false
columnDCorrect==false
But I would recommend using:
!columnACorrect
!columnBCorrect
!columnCCorrect
!columnDCorrect
It does the same thing. The 2nd option is more preferable.
I'm getting some peculiar output from a program in which I have a few if statements like this:
if((m.getLeft(position).state == position.state.wall || m.getLeft(position).state == position.state.border)
&& (m.getBelow(position).state == position.state.open || m.getBelow(position).state == position.state.visited)){
check = true;
}
where I have both && and || used in the same if condition. I want the boolean check to be made true if the cell at getLeft() is either a wall or a border AND the cell at getBelow() is either open or visited.
Does this code, the way I have it written now, perform this check properly? Perhaps more importantly, is it poor form to write a statement like this? Would it be better to break it up into two statements?
I'm not sure whether the peculiarities I'm seeing are resulting from these statements or something else, my question is more about general best practices.
EDIT: Thanks for all the input. I suspected as much (that it was too complicated), which was why I framed my question the way I did.
EDIT (a year later, looking back) (to restate the above more strenuously) for the love of god, don't write anything like the if statement above. If you find yourself with a similar line of code, remember occam's razor is perhaps nowhere more applicable than in programming.
Your complicated if statement can be refactored as:
if((m.getLeft(position).state == position.state.wall || m.getLeft(position).state == position.state.border)) {
if((m.getBelow(position).state == position.state.open || m.getBelow(position).state == position.state.visited)){
check = true;
}
}
Thanks to #Makoto:
check = ((m.getLeft(position).state == position.state.wall || m.getLeft(position).state == position.state.border)) && ((m.getBelow(position).state == position.state.open || m.getBelow(position).state == position.state.visited));
And your code, as well as this code "works".
But also, remember, stick to a naming convention that is mentioned in Java's Style Guidelines. I have no idea what m in your code is. This kind of naming an object reference must be avoided. Also, state seems to be a public field in your class (assuming). Such public access fields should also be avoided. Instead use getters() and setters().
It looks to me that it performs properly, however it is rather difficult to read.
If you're going to be using an && in an if statement, you may as well nest a new if statement instead, it is essentially the same thing in most cases.
Breaking down your boolean statement, it reads something like this:
(a == x_1 || a == x_2) && (b == x_3 || b == x_4)
Unfortunately, that's about as simple as that particular boolean statement will get. There are options to make the pain a lot easier:
Refactor your code to not need such complex statements, by breaking it up into two if-blocks (as shown in my refactor below), or
Extract that as a method and assign the return value to check. Honestly, it's either going to be true or false.
Here's an example of the refactor method. I don't know what m is precisely:
public boolean isCheck(M m, Position p) {
boolean retVal = false;
if(m.getLeft(p).state == p.state.wall || m.getLeft(p).state == p.state.border)) {
if((m.getBelow(p).state == p.state.open || m.getBelow(p).state == p.state.visited))
retVal = true;
}
}
return retVal;
}
// call it as such
check = isCheck(m, position);
Use another IF insted of using &&:
if(m.getLeft(position).state == position.state.wall ||
m.getLeft(position).state == position.state.border){
if(m.getBelow(position).state == position.state.open ||
m.getBelow(position).state == position.state.visited){
check = true;
}
}
//first
if(num % 2 == 0 ) {
isEven = true;
}
//second
isEven = (num %2 == 0);
What is the best thing to do, and is first case a case of code smell?
They don't do the same thing - if num is odd, the first leaves isEven with its previous value, the second sets it to false.
I would:
Try to initialize the variable at the point of declaration, and not change it afterwards.
Use the second form in preference to the first in general.
When the body of an if block is just setting a variable, and the value can be expressed as some simple modification of the condition of the if block, and you always want to set some value, I would just use the simple assignment.
The same goes for return statements - I would rather have:
return (num % 2 == 0); // Or (num & 1 == 0)
than
if (num % 2 == 0) {
return true;
} else {
return false;
}
Without knowing anything about the surrounding context, these two version actually differ in their semantics.
The first version will only change the value of isEven if num is an even number. The latter version will always update the value of isEven. So I would definitely prefer the latter, as it ensures isEven holds a useful semantic value.