161

I personally like the exclusive or, ^, operator when it makes sense in the context of boolean checks because of its conciseness. I much prefer to write

if (boolean1 ^ boolean2)
{
  //do it
}

than

if((boolean1 && !boolean2) || (boolean2 && !boolean1))
{
  //do it
}

but I often get confused looks from other experienced Java developers (not just the newbies), and sometimes comments about how it should only be used for bitwise operations.

I'm curious as to the best practices regarding the usage of the ^ operator.

nbro
  • 15,395
  • 32
  • 113
  • 196
Peter
  • 29,498
  • 21
  • 89
  • 122

12 Answers12

313

You can simply use != instead.

  • 37
    *"What's wrong with !="* `bool1 ^ bool2 ^ bool3` makes more logical sense to me than `bool1 != bool2 != bool3` – BlueRaja - Danny Pflughoeft May 05 '10 at 20:54
  • 4
    My brain hurts. So can != yield incorrect results or not? – deprecated Oct 14 '11 at 17:06
  • 28
    @vemv, `!=` yields correct results for `boolean`s (but not for `Boolean`s so be careful). It's not always pretty though, for example `(some != null) != (other != null)` isn't very readable. You either have to extract the parts in explicit booleans, or extract the `!=` in a separate method. – ivant Dec 22 '11 at 12:52
  • 23
    Here's why: `a ^ b` => "a or b but not both", `a != b` => "a is not equal to b". (What @RobertGrant said). Most humans would understand the first one easier if they know what xor is (which is pretty useful to know if you're in the field of computing...) – Harold R. Eason Nov 22 '13 at 20:53
  • 2
    @HaroldR.Eason important nitpicking here: `a != b` => "a is not IDENTICAL to b" – Mario Reutter Aug 04 '16 at 16:17
  • 1
    "Thus != behaves the same as ^ (§15.22.2) when applied to boolean operands." see https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.21.2 – Julien Feb 22 '18 at 11:14
  • When I come across that code I want to think _xor: exactly one of the operands is true_. Reading `!=` doesn't make me think that. This makes me prefer a comment or a method called xor, as suggested in other answers. – Joshua Goldberg May 30 '18 at 20:06
  • The question should be "if (b1 ^ b2 ^ b3)" , it means 2 of them are true and 1 is false. It will not lead to this answer that many people upvoted. – chipbk10 Dec 19 '18 at 12:20
  • minor nit: @chipbk10 - actually it means 1 or 3 of them are true ... an odd number of them must be true. But I agree with your point :) – ToolmakerSteve Oct 07 '19 at 07:42
27

I think you've answered your own question - if you get strange looks from people, it's probably safer to go with the more explicit option.

If you need to comment it, then you're probably better off replacing it with the more verbose version and not making people ask the question in the first place.

Martin
  • 1,328
  • 8
  • 11
  • 6
    I can assert you, you will get strange looks from me, when you seriously write `(boolean1 && !boolean2) || (boolean2 && !boolean1)` in a real life application code… – Holger May 05 '17 at 14:59
18

I find that I have similar conversations a lot. On the one hand, you have a compact, efficient method of achieving your goal. On the other hand, you have something that the rest of your team might not understand, making it hard to maintain in the future.

My general rule is to ask if the technique being used is something that it is reasonable to expect programmers in general to know. In this case, I think that it is reasonable to expect programmers to know how to use boolean operators, so using xor in an if statement is okay.

As an example of something that wouldn't be okay, take the trick of using xor to swap two variables without using a temporary variable. That is a trick that I wouldn't expect everybody to be familiar with, so it wouldn't pass code review.

nbro
  • 15,395
  • 32
  • 113
  • 196
Dave Tarkowski
  • 634
  • 3
  • 4
14

I think it'd be okay if you commented it, e.g. // ^ == XOR.

nbro
  • 15,395
  • 32
  • 113
  • 196
Dre
  • 4,298
  • 30
  • 39
10

You could always just wrap it in a function to give it a verbose name:

public static boolean XOR(boolean A, boolean B) {
    return A ^ B;
}

But, it seems to me that it wouldn't be hard for anyone who didn't know what the ^ operator is for to Google it really quick. It's not going to be hard to remember after the first time. Since you asked for other uses, its common to use the XOR for bit masking.

You can also use XOR to swap the values in two variables without using a third temporary variable.

// Swap the values in A and B
A ^= B;
B ^= A;
A ^= B;

Here's a Stackoverflow question related to XOR swapping.

zb226
  • 9,586
  • 6
  • 49
  • 79
Cory Gross
  • 36,833
  • 17
  • 68
  • 80
6
if((boolean1 && !boolean2) || (boolean2 && !boolean1)) 
{ 
  //do it 
} 

IMHO this code could be simplified:

if(boolean1 != boolean2) 
{ 
  //do it 
} 
Y--
  • 77
  • 1
  • 1
5

With code clarity in mind, my opinion is that using XOR in boolean checks is not typical usage for the XOR bitwise operator. From my experience, bitwise XOR in Java is typically used to implement a mask flag toggle behavior:

flags = flags ^ MASK;

This article by Vipan Singla explains the usage case more in detail.

If you need to use bitwise XOR as in your example, comment why you use it, since it's likely to require even a bitwise literate audience to stop in their tracks to understand why you are using it.

nbro
  • 15,395
  • 32
  • 113
  • 196
Gunnar Karlsson
  • 28,350
  • 10
  • 68
  • 71
0

I personally prefer the "boolean1 ^ boolean2" expression due to its succinctness.

If I was in your situation (working in a team), I would strike a compromise by encapsulating the "boolean1 ^ boolean2" logic in a function with a descriptive name such as "isDifferent(boolean1, boolean2)".

For example, instead of using "boolean1 ^ boolean2", you would call "isDifferent(boolean1, boolean2)" like so:

if (isDifferent(boolean1, boolean2))
{
  //do it
}

Your "isDifferent(boolean1, boolean2)" function would look like:

private boolean isDifferent(boolean1, boolean2)
{
    return boolean1 ^ boolean2;
}

Of course, this solution entails the use of an ostensibly extraneous function call, which in itself is subject to Best Practices scrutiny, but it avoids the verbose (and ugly) expression "(boolean1 && !boolean2) || (boolean2 && !boolean1)"!

ONE
  • 567
  • 7
  • 15
-2

If the usage pattern justifies it, why not? While your team doesn't recognize the operator right away, with time they could. Humans learn new words all the time. Why not in programming?

The only caution I might state is that "^" doesn't have the short circuit semantics of your second boolean check. If you really need the short circuit semantics, then a static util method works too.

public static boolean xor(boolean a, boolean b) {
    return (a && !b) || (b && !a);
}
Alan
  • 7,066
  • 5
  • 30
  • 38
  • 16
    I don't see any short circuiting possible with xor - you have to know both a and b to evaluate the result. – Thelema Oct 02 '08 at 03:46
  • 7
    Also, the arguments would be evaluated att call time, so no short-circuiting will happen whatsoever. – erikkallen Jan 06 '09 at 10:25
  • 3
    Additionally, xor should be a single operation at the machine level. – Ogre Psalm33 Mar 18 '13 at 13:25
  • You should probably look up the difference between short-circuit evaluation and lazy evaluation. Short-curcuit evaluation is a code style that that prevents calls that would otherwise result in runtime errors, such as division by zero. In C this can be ´if (denominator != 0 && numerator / denominator)´, which in it self utilizes lazy evaluation to prevent division by zero. Your answer is also purely speculative. – Martin Jun 19 '13 at 10:36
  • 2
    To be honest, a programmer writing a function `xor`, that does exactly what the xor operator does but in a roundabout way, would bring up more questions in my mind (specifically about competence) than a programmer that just used `^`. – Stijn de Witt Jun 05 '17 at 14:00
  • This answer makes no sense. Consider the 4 possible inputs to xor. Now examine what happens, in each of the 4 cases, in your complex expression. *Of course* in all of the 4 cases, both a and b get evaluated, before the result is known. If that didn't happen, you would have failed to calculate an xor. There is no short circuiting (except in the trivial sense that the unnecessarily complex expression doesn't get completely evaluated). – ToolmakerSteve Oct 07 '19 at 08:02
-2

As a bitwise operator, xor is much faster than any other means to replace it. So for performance critical and scalable calculations, xor is imperative.

My subjective personal opinion: It is absolutely forbidden, for any purpose, to use equality (== or !=) for booleans. Using it shows lack of basic programming ethics and fundamentals. Anyone who gives you confused looks over ^ should be sent back to the basics of boolean algebra (I was tempted to write "to the rivers of belief" here :) ).

Nick
  • 37
  • 1
  • 1
    Except that the JIT is extremely good at keyhole (little) optimizations, like replacing one boolean expression with another. – David Leppik Nov 09 '11 at 17:00
  • 1
    Also, ^ isn't primarily a Boolean (logic) operator, it's a bitwise operator. It tells the reader to slow down, because there are likely to be sign bugs. If you use ^ for !=, you're going to get really messed up if you ever program in C. Bitwise operators are a signal to your readers (those who debug your code, including you) to slow down and look for sign errors. And they can be tricky. For example, did you know that Java's % isn't true modulo, like in C or Python? I once had a snippet of code that ran the same in C, JavaScript, and Python, but not in Java. – David Leppik Nov 09 '11 at 17:15
  • 6
    How did this ever get upvoted? First of all, in Java XOR and != are compiled [http://stackoverflow.com/a/4175512/202504](to the exact same code), second even in assembler testing for equality and xor are single simple operations each. Do you have any numbers to back up your statement? – jmiserez Nov 17 '13 at 13:42
-3
str.contains("!=") ^ str.startsWith("not(")

looks better for me than

str.contains("!=") != str.startsWith("not(")
Henrik Heimbuerger
  • 9,924
  • 6
  • 56
  • 69
Chris Rea
  • 151
  • 2
  • 7
-3

!= is OK to compare two variables. It doesn't work, though, with multiple comparisons.