296

Observations:

Java has a logical AND operator.
Java has a logical OR operator.
Java has a logical NOT operator.

Problem:

Java has no logical XOR operator, according to sun. I would like to define one.

Method Definition:

As a method it is simply defined as follows:

public static boolean logicalXOR(boolean x, boolean y) {
    return ( ( x || y ) && ! ( x && y ) );
}


Method Call:

This method is called in the following way:

boolean myVal = logicalXOR(x, y);


Operator Usage:

I would much rather have an operator, used as follows:

boolean myVal = x ^^ y;


Question:

I can't find anything on how to go about defining a new operator in Java. Where should I start?

starblue
  • 55,348
  • 14
  • 97
  • 151
eleven81
  • 6,301
  • 11
  • 37
  • 48
  • 1
    what? the link you gave has the content 'bitwise exclusive OR' – Mathew P. Jones Mar 10 '15 at 13:37
  • were you wondering then if you could define operators in Java like you can in C++? – avgvstvs May 27 '15 at 23:59
  • 1
    It seems you misunderstood the difference between & and &&. Both are logical operators (on a boolean). Starblue's answer covers it more widely. – Vlasec Aug 04 '16 at 10:45
  • just because it is not in the **tutorial**, does not mean that Java does not have it - tutorials are not (always) complete. See [Java Language Specification 15.22.2](https://docs.oracle.com/javase/specs/jls/se6/html/expressions.html#15.22.2) – user85421 Aug 19 '16 at 09:24
  • 8
    It's called `!=`, there is also a logical XNOR called `==` – Mark K Cowan Mar 12 '18 at 20:42

19 Answers19

748

Java does have a logical XOR operator, it is ^ (as in a ^ b).

Apart from that, you can't define new operators in Java.

Edit: Here's an example:

public static void main(String[] args) {
    boolean[] all = { false, true };
    for (boolean a : all) {
        for (boolean b: all) {
            boolean c = a ^ b;
            System.out.println(a + " ^ " + b + " = " + c);
        }
    }
}

Output:

false ^ false = false
false ^ true = true
true ^ false = true
true ^ true = false
Community
  • 1
  • 1
javashlook
  • 10,341
  • 1
  • 26
  • 33
  • 5
    This escaped my memory too when I wrote my post, but I think you CAN use ^ as a logical operator (as well as bitwise). – Neil Coffey Apr 07 '09 at 17:06
  • 157
    ^ is not only a bitwise operator. It is also a logical operator. The ^ operator is overloaded. It operates on integral types or boolean types. +1 for a great answer javashlook. Eddie, it doesn't get more explicit than JLS Section 15.22.2, "Boolean Logical Operators &, ^, and |". – erickson Apr 07 '09 at 17:25
  • 2
    @mmyers: Check out the link the OP just edited in. Sun, in "Learning the Java Language," lists a logical OR, bitwise OR, bitwise XOR, and so on, but no logical XOR. Effectively, yes, there is one. But it's inconsistent. Why do we have && and || but not ^^, and &, |, ^ can be used in the same way – Eddie Apr 07 '09 at 17:40
  • 101
    And of course, the answer is that && and || will skip evaluating the 2nd part of the expression and & and | will always evaluate both parts of the expression (from my read of JLS). A ^^ would always have to evaluate both parts, by definition, so behaves identically to ^. Probably why there's no ^^ – Eddie Apr 07 '09 at 17:45
  • 83
    @Eddie: That and ^^ just looks too much like an emoticon. – Michael Myers Apr 07 '09 at 17:47
  • 5
    Maybe it's a matter of semantics, but when it comes to XOR, bitwise and logical yield the same result. Therefore, no need for distinct operators. The simplified truth table for a XOR operator is X ^ !X = 1. You cannot short circuit an input in XOR because you have to determine whether the inputs are different. It is a lot easier to understand if you know the fabrication of the actual XOR gate. – hfontanez Apr 09 '15 at 20:31
  • 1
    The only reason to use & or | as a logical operator that I can think of is to evaluate both sides when they have some desirable side effects. This results in people ignoring them (as logical operators) to the point the newbies don't even know they are logical operators at all. – Vlasec Aug 04 '16 at 10:55
  • I'd say `&&` is the "normal" one for most people – Mark Mar 15 '19 at 15:30
  • 2
    BTW: It could be repleced by simple `a != b` – Grigory Kislin Jun 28 '19 at 20:01
335

Isn't it x != y ?

Maurice Perry
  • 32,610
  • 9
  • 70
  • 97
  • 5
    If x and y are booleans, then the logic table for xor and != are identical: t,t => f ; t,f => t; f,t => t; f,f => f – Greg Case Apr 07 '09 at 17:15
  • 86
    Maurice: Arrgh you just blew my mind! How did I never notice this? –  Apr 07 '09 at 17:35
  • Wow! that was a controversal one! I guess that ^ is a better answer if you are interested in boolean arithmetics, and that one is better to if you just want to compare two boolean values. – Maurice Perry Apr 07 '09 at 19:33
  • 8
    @Milhous Are you saying `a != b != c` won't work, but `a ^ b ^ c` will? In that case, [you are wrong](https://ideone.com/8lQRmF). – fredoverflow Mar 01 '14 at 00:41
  • 3
    Maurice, just brilliant! It happens to me to lose simple things from sight when there is a lot to do:) – sberezin Sep 09 '14 at 08:31
  • 3
    @Milhous What do you expect out of `a ^ b ^ ... ^ z`? If you want a true result only when **one** of the variables is true, you will be very disappointed. Both a chain of `^` and of `!=` return true if the number of true variables is **odd**. Something to keep in mind. – Tobia Mar 17 '15 at 15:22
  • As well as `!=` for XOR, you get `==` for XNOR. Unfortunately, there are no builtin symbols for NAND and NOR. `!&` and `!|` would have been cool. – Tobia Mar 17 '15 at 15:31
  • 1
    This is not type safe – ZhekaKozlov Nov 22 '16 at 07:02
  • 8
    This approch implodes when both sides are wrapper classes, `new Boolean(true) != new Boolean(true)` gives `true`. – Vlastimil Ovčáčík Jan 21 '17 at 12:50
  • @VlastimilOvčáčík And how does the alternative, operator `^` fare? I guess it implodes as well.... – Stijn de Witt Jun 05 '17 at 13:49
  • 2
    @StijndeWitt no, it doesn't: ^ doesn't apply to objects whereas != does. – Maurice Perry Jun 06 '17 at 18:10
  • I prefer this solution because of readability. ^ is very very rare. – Balázs Németh Sep 30 '19 at 10:08
  • 1
    @VlastimilOvčáčík - that's why you never use `new Boolean`. That constructor (like most constructors) shouldn't have been public. Use `Boolean.valueOf`. – Doradus Jan 29 '20 at 21:04
78

Java has a logical AND operator.
Java has a logical OR operator.

Wrong.

Java has

  • two logical AND operators: normal AND is & and short-circuit AND is &&, and
  • two logical OR operators: normal OR is | and short-circuit OR is ||.

XOR exists only as ^, because short-circuit evaluation is not possible.

Michael Myers
  • 188,989
  • 46
  • 291
  • 292
starblue
  • 55,348
  • 14
  • 97
  • 151
  • 2
    Interesting comment. Is that documented? – user666412 Mar 28 '13 at 15:13
  • 1
    I think & and | are not short-circuit because they are bitwise operators. And in fact it's not possible to short-circuit them. – Krzysztof Jabłoński May 14 '13 at 07:36
  • 4
    @Krzysztof Jabłoński They are bitwise operators on numbers, but here we are talking about boolean expressions. – starblue May 14 '13 at 20:36
  • 3
    @user666412 Yes, in the Java Language Specification (where else?). – starblue May 14 '13 at 20:38
  • 21
    If it has 2 AND operators and 2 OR operators then the statements 'Java has a logical AND operator' and 'Java has a logical OR operator' are not wrong. By definition if you have 2 of something then you also have 1 of it. – RyanfaeScotland May 20 '13 at 12:42
  • @RyanfaeScotland Don't take that "wrong" too seriously, I just wanted to drive home the point. What's actually wrong (and also wrong in the Sun tutorial) is that Java has no XOR operator. – starblue Feb 25 '16 at 10:31
  • 2
    Can't help but take it seriously when someone returns a one word sentence reply! – RyanfaeScotland Feb 25 '16 at 10:47
  • 1
    For clarity, the symbols &, ^, and | are overloaded as bitwise operators (see [JLS 15.22.1](https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.22.1)) and boolean logical operators (see [JLS 15.22.2](https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.22.1) ). && and || are Conditional AND and OR logical operators (JLS [15.23](https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.23) and [15.24](https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.24)), that support the short circuit; there is no conditional bitwise version. – Pixelstix Dec 05 '16 at 16:42
34

Perhaps you misunderstood the difference between & and &&, | and || The purpose of the shortcut operators && and || is that the value of the first operand can determine the result and so the second operand doesn't need to be evaluated.

This is especially useful if the second operand would results in an error. e.g.

if (set == null || set.isEmpty())
// or
if (list != null && list.size() > 0)

However with XOR, you always have to evaluate the second operand to get the result so the only meaningful operation is ^.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
25

You can just write (a!=b)

This would work the same as way as a ^ b.

Shuliyey
  • 415
  • 4
  • 7
13

Logical exclusive-or in Java is called !=. You can also use ^ if you want to confuse your friends.

Doradus
  • 938
  • 1
  • 9
  • 15
10

The following your code:

public static boolean logicalXOR(boolean x, boolean y) {
    return ( ( x || y ) && ! ( x && y ) );
}

is superfluous.

Why not to write:

public static boolean logicalXOR(boolean x, boolean y) {
    return x != y;
}

?

Also, as javashlook said, there already is ^ operator.

!= and ^ work identically* for boolean operands (your case), but differently for integer operands.

* Notes:
1. They work identically for boolean (primitive type), but not Boolean (object type) operands. As Boolean (object type) values can have value null. And != will return false or true when one or both of its operands are null, while ^ will throw NullPointerException in this case.
2. Although they work identically, they have different precedence, e.g. when used with &: a & b != c & d will be treated as a & (b != c) & d, while a & b ^ c & d will be treated as (a & b) ^ (c & d) (offtopic: ouch, C-style precedence table sucks).

Sasha
  • 3,599
  • 1
  • 31
  • 52
  • 1
    For Boolean values I like `!=` – GKalnytskyi May 13 '16 at 06:10
  • 1
    @GKalnytskyi for `Boolean` values `!=` works incorrectly. For `boolean` values it's ok. – vadipp Jun 27 '17 at 05:53
  • 2
    != and ^ do not work *identically* for boolean operands. You'll get different results for "false & false != true" versus "false & false ^ true" because of precedence. – Albert Hendriks Dec 16 '17 at 21:03
  • 1
    @AlbertHendriks, I'd better say that they _work_ identically, but have different _precedence_ (though it's just a matter of terminology). – Sasha Dec 17 '17 at 00:34
9

That's because operator overloading is something they specifically left out of the language deliberately. They "cheated" a bit with string concatenation, but beyond that, such functionality doesn't exist.

(disclaimer: I haven't worked with the last 2 major releases of java, so if it's in now, I'll be very surprised)

Kevin Anderson
  • 6,850
  • 4
  • 32
  • 54
7

The only operator overloading in Java is + on Strings (JLS 15.18.1 String Concatenation Operator +).

The community has been divided in 3 for years, 1/3 doesn't want it, 1/3 want it, and 1/3 doesn't care.

You can use unicode to create method names that are symbols... so if you have a symbol you want to use you could do myVal = x.$(y); where $ is the symbol and x is not a primitive... but that is going to be dodgy in some editors and is limiting since you cannot do it on a primitive.

TofuBeer
  • 60,850
  • 18
  • 118
  • 163
6

Here is a var arg XOR method for java...

public static boolean XOR(boolean... args) {
  boolean r = false;
  for (boolean b : args) {
    r = r ^ b;
  }
  return r;
}

Enjoy

  • This feels like its going to have some very strange behaviour. E.g. `XOR(true,true,true)` returns true, which seems not like what you'd expect from a method called `XOR`. My expected behaviour would be that it always returns false (which is of course not helpful) – Richard Tingle Oct 20 '18 at 08:01
2

You can use Xtend (Infix Operators and Operator Overloading) to overload operators and 'stay' on Java

Kelvin
  • 20,119
  • 3
  • 60
  • 68
iga
  • 41
  • 1
  • 5
  • Note that Xtend doesn't allow you to override the caret `^`; you must use `bool_1.xor(bool_2)`. Oddly, the parser doesn't even allow you to *use* the caret; you must use `xor` for booleans and `bitwiseXor` for integers. You could, of course, overload another operator, but that would get very confusing. – Kelvin Jun 20 '16 at 19:24
2

What you're asking for wouldn't make much sense. Unless I'm incorrect you're suggesting that you want to use XOR to perform Logical operations the same way AND and OR do. Your provided code actually shows what I'm reffering to:

public static boolean logicalXOR(boolean x, boolean y) {
    return ( ( x || y ) && ! ( x && y ) );
}

Your function has boolean inputs, and when bitwise XOR is used on booleans the result is the same as the code you've provided. In other words, bitwise XOR is already efficient when comparing individual bits(booleans) or comparing the individual bits in larger values. To put this into context, in terms of binary values any non-zero value is TRUE and only ZERO is false.

So for XOR to be applied the same way Logical AND is applied, you would either only use binary values with just one bit(giving the same result and efficiency) or the binary value would have to be evaluated as a whole instead of per bit. In other words the expression ( 010 ^^ 110 ) = FALSE instead of ( 010 ^^ 110 ) = 100. This would remove most of the semantic meaning from the operation, and represents a logical test you shouldn't be using anyway.

2

I am using the very popular class "org.apache.commons.lang.BooleanUtils"

This method is tested by many users and safe. Have fun. Usage:

boolean result =BooleanUtils.xor(new boolean[]{true,false});
Adam111p
  • 3,469
  • 1
  • 23
  • 18
1

A and B would have to be boolean values to make != the same as xor so that the truth table would look the same. You could also use !(A==B) lol.

1

This is an example of using XOR(^), from this answer

byte[] array_1 = new byte[] { 1, 0, 1, 0, 1, 1 };
byte[] array_2 = new byte[] { 1, 0, 0, 1, 0, 1 };

byte[] array_3 = new byte[6];

int i = 0;
for (byte b : array_1)
    array_3[i] = b ^ array_2[i++];

Output

0 0 1 1 1 0
Asyraf
  • 609
  • 6
  • 14
0

Because boolean data type is stored like an integer, bit operator ^ functions like a XOR operation if used with boolean values.

//©Mfpl - XOR_Test.java

    public class XOR_Test {
        public static void main (String args[]) {
            boolean a,b;

            a=false; b=false;
            System.out.println("a=false; b=false;  ->  " + (a^b));

            a=false; b=true;
            System.out.println("a=false; b=true;  ->  " + (a^b));

            a=true;  b=false;
            System.out.println("a=true;  b=false;  ->  " + (a^b));

            a=true; b=true;
            System.out.println("a=true; b=true;  ->  " + (a^b));

            /*  output of this program:
                    a=false; b=false;  ->  false
                    a=false; b=true;  ->  true
                    a=true;  b=false;  ->  true
                    a=true; b=true;  ->  false
            */
        }
    }
user207421
  • 305,947
  • 44
  • 307
  • 483
Ledón
  • 31
  • 2
0

Here's an example:

Given 2 int values, return true if one is negative and one is positive. Except if the parameter "negative" is true, then return true only if both are negative.

    public boolean posNeg(int a, int b, boolean negative) {
      if(!negative){
        return (a>0 && b<0)^(b>0 && a<0);
      }
      else return (a<0 && b<0);
    }
SpicyCatGames
  • 863
  • 7
  • 25
0

you'll need to switch to Scala to implement your own operators

pipe example

mut1na
  • 795
  • 6
  • 21
0

Can be achieved using stream API in java 8 and above

public static boolean logicalXOR(boolean x, boolean y) {  // can modify to take [] or list of bools
    return Stream.of(x, y)  // modify as per method params
        .filter(bool -> bool)
        .count() == 1;
}
Harsh Gundecha
  • 1,139
  • 9
  • 16