views:

608

answers:

8

My question might be very basic but still I think it worths to ask. I have the following code:

if(!partialHits.get(req_nr).containsKey(z) || partialHits.get(req_nr).get(z) < tmpmap.get(z)){  
    partialHits.get(z).put(z, tmpmap.get(z));  
}

where partialHits is a HashMap. What will happen if the first statement is true? Will Java still check the second statement? Because in order the first statement to be true, the HashMap should not contain the given key, so if the second statement is checked, I will get NullPointerException.
So in simple words, if we have the following code

if(a && b)  
if(a || b)

would Java check b if a is false in the first case and if a is true in the second case?

+13  A: 

No it will not be checked. This behaviour is called short-circuit evaluation and is a feature in many languages including Java.

Peter van der Heijden
Thanks for your reply. Unfortunately I lack some basic programming knowledge but at the same time I think one should not hesitate to ask anyway :)
Azimuth
@Azimuth: You are most welcome. If you don't know something, the best way to fix that is to ask.
Peter van der Heijden
+4  A: 

No, if a is true (in a or test), b will not be tested, as the result of the test will always be true, whatever is the value of the b expression.

Make a simple test:

if (true || ((String) null).equals("foobar")) {
    ...
}

will not throw a NullPointerException!

romaintaz
+3  A: 

No it won't, Java will short-circuit and stop evaluating once it knows the result.

abyx
+11  A: 

No it will not be evaluated. And this is very useful. Like you need to test, if a String is not null or empty, you can write:

if (str != null && !str.isEmpty()) {
  doSomethingWith(str.charAt(0));
}

or, the other way round

if (str == null || str.isEmpty()) {
  complainAboutUnusableString();
} else {
  doSomethingWith(str.charAt(0));
}

If we hadn't 'short-circuits' in Java, we'd receive a lot of NullPointerExceptions in the above lines of code.

Andreas_D
Do bitwise comparisons exist so you _can_ evaluate both expressions? i.e. if(str != null | str.isEmpty()) ? (of course this isn't a practical example, in fact it's stupid, but you get the idea)
Kezzer
As long as the expressions don't have side effects, short-circuit semantics are logically equivalent to complete evaluation. That is, if A is true, you know A||B is true without having to evaluate B. The only time it will make a difference is if an expression has side effects. As for other operators, you can use `*` and `+` as logical `and` and `or`; `((A?1:0) * (B?1:0)) == 1`, `((A?1:0) + (B?1:0)) > 0`. You can even do `xor`: `((A?1:0) + (B?1:0)) == 1`.
outis
@Kezzer: is that really bitwise comparison? I think it is a `boolean` (logical) operator. It's different than the `bitwise` (integer) operator, despite having the same symbol...
Carlos Heuberger
+4  A: 

All the answers here are great but, just to illustrate where this comes from, for questions like this it's good to go to the source: the Java Language Specification.

Section 15:23, Conditional-And operator (&&), says:

The && operator is like & (§15.22.2), but evaluates its right-hand operand only if the value of its left-hand operand is true. [...] At run time, the left-hand operand expression is evaluated first [...] if the resulting value is false, the value of the conditional-and expression is false and the right-hand operand expression is not evaluated. If the value of the left-hand operand is true, then the right-hand expression is evaluated [...] the resulting value becomes the value of the conditional-and expression. Thus, && computes the same result as & on boolean operands. It differs only in that the right-hand operand expression is evaluated conditionally rather than always.

And similarly, Section 15:24, Conditional-Or operator (||), says:

The || operator is like | (§15.22.2), but evaluates its right-hand operand only if the value of its left-hand operand is false. [...] At run time, the left-hand operand expression is evaluated first; [...] if the resulting value is true, the value of the conditional-or expression is true and the right-hand operand expression is not evaluated. If the value of the left-hand operand is false, then the right-hand expression is evaluated; [...] the resulting value becomes the value of the conditional-or expression. Thus, || computes the same result as | on boolean or Boolean operands. It differs only in that the right-hand operand expression is evaluated conditionally rather than always.

A little repetitive, maybe, but the best confirmation of exactly how they work. Similarly the conditional operator (?:) only evaluates the appropriate 'half' (left half if the value is true, right half if it's false), allowing the use of expressions like:

int x = (y == null) ? 0 : y.getFoo();

without a NullPointerException.

Cowan
+2  A: 

Yes, the short-circuit evaluation for boolean expressions is the default behaviour in all the C-like family.

An interesting fact is that Java also uses the & and | as logic operands (they are overloaded, with int types they are the expected bitwise operations) to evaluate all the terms in the expression, which is also useful when you need the side-effects.

fortran
+1  A: 

Java has 4 different boolean compare operators: &, &&, |, ||

& and && are "and" operators, | and || "or" operators.

The single ones will check every parameter, regardless of the values, before checking the values of the parameters. The double ones will first check the left parameter and its value and if true (||) or false (&&) leave the second one untouched. Sound compilcated? An easy example should make it clear:

Given for all examples:

 String aString = null;

AND:

 if (aString != null & aString.equals("lala"))

Both parameters are checked before the evaluation is done and a NullPointerException will be thrown for the second parameter.

 if (aString != null && aString.equals("lala"))

The first parameter is checked and it returns false, so the second paramter won't be checked, because the result is false anyway.

The same for OR:

 if (aString == null | !aString.equals("lala"))

Will raise NullPointerException, too.

 if (aString == null || !aString.equals("lala"))

The first parameter is checked and it returns true, so the second paramter won't be checked, because the result is true anyway.

Hardcoded
aioobe
Oh, I wasn't aware it checks boolean boolean values, too. Only used it for bitmasks, so far.
Hardcoded
A: 

This goes back to the basic difference between & and &&, | and ||

BTW you perform the same tasks many times. Not sure if efficiency is an issue. You could remove some of the duplication.

Z z2 = partialHits.get(req_nr).get(z); // assuming a value cannout be null.
Z z3 = tmpmap.get(z); // assuming z3 cannot be null.
if(z2 == null || z2 < z3){   
    partialHits.get(z).put(z, z3);   
} 
Peter Lawrey