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;
}
}
Related
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.
I am very new to Java (doing a beginners university module) so sorry for the probably silly question. I am trying to verify whether a ragged array is a 'tridiagonal matrix'.
It is valid if it is of length 3 at the first level and of length n − 1, n, and n − 1 at the second level. I intended to come up with a code to firstly verify the length is 3, then find the longest length array within it for n, then finally verify each length.
For whatever reason my code won't compile but I'm not seeing an error message, just a red exclamation mark on the class. I assume this means there are multiple errors. If anyone could point them out it would be a massive help.
static boolean isValidTridiagonal ( double [][] m)
{
if (double [][]=new double [3][])
{
int n = 0;
for(int i = 0; i < m.length; i++)
{
if(m[i].length > n)
{
n = m[i].length;
if( (m[0].length = n-1) && (m[1].length = n) &&(m[2].length=n-1))
{
return true
}
else
{
return false
}
}
else
{
return false
}
}
Thanks very much!
I agree with Foolish in the comments that it's helpful to use an IDE that can highlight syntax errors and other problems with the code, it really makes a huge difference. Apart from that, another general strategy is to always code in "baby steps": do only the minimal thing to test if the code works, compile and test often. And if you still have troubles, you can always comment out chunks of your code when searching for the offending bits.
Having said that, the errors that I see in your code are:
if (double [][]=new double[3][])
If you want to test the length of the input, you can do if (m.length == 3)
In
if( (m[0].length = n-1) && (m[1].length = n) &&(m[2].length=n-1))
you're not testing for equality, but rather trying to put the values n-1 etc into m[0].length, which is not going to work. What you probably meant was
if( (m[0].length == n-1) && (m[1].length == n) &&(m[2].length==n-1))
In
return true
you're missing a semicolon. The compiler is whiny about things like that and unless you use an IDE or learn to interpret the compiler error messages, it can be really painful to find such errors.
Finally, of course, the answer by vasste provides a much simpler solution to your actual task, so it's worth looking into that :).
Why do you need all that loops? If all arrays cannot be null, than
static boolean isValidTridiagonal(double[][] m) {
return m.length == 3 && m[0].length == m[1].length - 1 && m[2].length == m[0].length;
}
You're missing a few braces at the end but, judging from your indentation, you just forgot to copy them.
You're missing semicolons from the end of the return lines.
The condition within this if statement if (double [][] = new double [3][]) is not a valid expression. You simply want to evaluate the length, which you can do like if (m.length == 3). You did the same thing later on.
The line including (m[0].length = n-1) && (m[1].length = n) && (m[2].length=n-1) is not valid because you are performing assignment (=) in all three cases. An equality check is the double equals operator ==.
You do not return a value in every case. You can fix this by adding return false; after the closing brace of your first if statement, i.e. the last line of the function.
This is enough to get your code to compile. As mentioned in another answer though, your logic is confusing and without actually tracing it through I would speculate that it will not work as you would expect.
If I have understood your requirements correctly, you can rewrite the entire function as:
static boolean isValidTridiagonal ( double [][] m)
{
return m.length == 3 &&
m[0].length + 1 == m[1].length &&
m[2].length + 1 == m[1].length;
}
A proper IDE - Netbeans, Eclipse, etc. - will give you fairly descriptive error messages to show you where you've gone wrong.
This is basically completely stylistic but I wish someone had pointed this out to me earlier. If you ever find yourself writing code in this form:
if( (m[0].length == n-1) && (m[1].length == n) && (m[2].length == n-1))
{
return true;
}
else
{
return false;
}
know that you can save yourself so many lines without losing any readability by instead writing:
return (m[0].length == n-1) && (m[1].length == n) && (m[2].length == n-1);
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.
I am writing a method, and would like to know if the attached code is efficient depending on how it is written:
public boolean isThreeOfKind(PlayingCard[] hand)
{
// if(hand[0].getRank() == hand[2].getRank())
// return true;
// else if(hand[1].getRank() == hand[3].getRank())
// return true;
// else if(hand[2].getRank() == hand[4].getRank())
// return true;
return (hand[0].getRank() == hand[2].getRank() ||
hand[1].getRank() == hand[3].getRank() ||
hand[2].getRank() == hand[4].getRank());
}
So as you can see I have an if else if statement commented out, and a return statement doing the same thing basically, which would be more efficient and according to coding standards?
No difference in efficiency, but definite difference in style, the second one being much better. However, this particular logic is really just
for (int i = 0; i < 3; i++)
if (hand[i].getRank() == hand[i+2].getRank()) return true;
return false;
This type of question might be better on CodeReview because it's more of an opinion. But In my opinion it's much easier to read the non-commented portion and performance shouldn't be worried about until it becomes an issue (especially in something like this). For more on that see the Program optimization article on Wikipedia particularly the When to Optimize section.
As Jeffery said, I'd say readability is more valuable than efficiency in this case (I wouldn't say that's a universal rule).
You might be interested in a concept called Short-Circuit Evaluation. Notice that || is a short-circuit operator in Java. As such, you'll get the same effect as the if statements if the first statement is true (the other two will not be evaluated).
That being said, I'm not sure if those two bits of code compile down into the same function (they might depending on the compiler implementation). If they do not compile down the same, the second will likely be faster.
Or if you prefer only one exit point in the method and array boundary checking:
boolean found = false;
for (int i = 0; !found && i < hand.length - 2; i++)
found = (hand[i].getRank() == hand[i + 2].getRank());
return found;
Which of the 2 is better from a processing or optimizing point of view?
I feel Option 1 is more readable, but I've been told Option 2 is more efficient. Is that so?
if (value != null) {
if (value.equalsIgnoreCase(ApplicationConstants.A)) {
} else if (value.equalsIgnoreCase(ApplicationConstants.B)) {
}
}
Option 2:
if ((value != null) && (value.equalsIgnoreCase(ApplicationConstants.A))) {
} else if ((value != null) && (value.equalsIgnoreCase(ApplicationConstants.B))) {
}
There's nothing here to care about performance wise, write your code so it's as readable as you can make it.
When performance testing later highlights areas that need to be optimized then and only then optimize only the places that need it.
To make it more readable you can invert your tests to get rid of the null check:
if (ApplicationConstants.A.equalsIgnoreCase(value)) {
} else if (ApplicationConstants.B.equalsIgnoreCase(value)) {
}
Option 1 is efficient since there is no redundant null check.
I'd expect the first to be slightly more efficient, because && is short-circuit, so it gives multiple conditional branches anyway. But if you want to be certain, time them.
I would go with option 1 as in option 2, more no of comparisons are made.
The first option is better as with one condition check you can decide.
so if value != null then only it will enter else it will not even enter the conditional block.
But in 2nd option it will check if condition , and if false also it wd check else condition (for value == null).