在Java中创建“逻辑异或”运算符


274

观察结果:

Java具有逻辑AND运算符。
Java具有逻辑或运算符。
Java具有逻辑NOT运算符。

问题:

据sun称,Java没有逻辑XOR运算符。我想定义一个。

方法定义:

作为一种方法,其简单定义如下:

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


方法调用:

可以通过以下方式调用此方法:

boolean myVal = logicalXOR(x, y);


操作员用法:

我宁愿有一个运算符,其用法如下:

boolean myVal = x ^^ y;


题:

关于如何在Java中定义新运算符,我找不到任何东西。我应该从哪里开始?


1
什么?您提供的链接的内容为“按位异或”
Mathew P. Jones

您是否想知道是否可以像在C ++中那样在Java中定义运算符?
avgvstvs 2015年

1
似乎您误解了&和&&之间的区别。两者都是逻辑运算符(布尔值)。Starblue的答案涵盖了更广泛的范围。
Vlasec

仅仅因为它不在本教程中,并不意味着Java没有它-教程(总是)不完整。参见Java语言规范15.22.2
user85421 '16

5
这称为!=,还有一个逻辑XNOR称为==
Mark K Cowan,

Answers:


695

Java 确实有一个逻辑XOR运算符,它是^(如中的a ^ b)。

除此之外,您无法在Java中定义新的运算符。

编辑:这是一个示例:

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);
        }
    }
}

输出:

假^假=假
假^真=真
正确^错误=正确
正确^正确=否

5
当我写我的帖子时,这也逃脱了我的记忆,但是我认为您可以将^用作逻辑运算符(以及按位运算符)。
尼尔·科菲

144
^不仅是按位运算符。它也是一个逻辑运算符。^运算符已重载。它对整数类型或布尔类型进行操作。+1是一个很好的答案javashlook。Eddie,它没有JLS第15.22.2节“布尔逻辑运算符&,^和|”更明确。
erickson

97
当然,答案是&&和|| 将跳过对表达式和&和|的第二部分的求值。将始终对表达式的两个部分求值(根据我对JLS的阅读)。根据定义,^^始终必须同时评估两个部分,因此其行为与^相同。可能是为什么没有^^
Eddie

81
@Eddie:那和^^看起来太像图释了。
Michael Myers

5
也许这是语义问题,但是当涉及到XOR时,按位和逻辑将产生相同的结果。因此,不需要不同的运算符。XOR运算符的简化真值表为X ^!X =1。您不能在XOR中使输入短路,因为您必须确定输入是否不同。如果您知道实际的XOR门的制造,则更容易理解。
hfontanez 2015年

305

是x!= y吗?


5
如果x和y为布尔值,则xor和!=的逻辑表相同:t,t => f; t,f => t; f,t => t; f,f => f
Greg Case

81
莫里斯(Maurice):哎呀,你真让我震惊!我怎么没注意到这一点?

8
@Milhous你是说a != b != c不会,但是a ^ b ^ c会吗?在这种情况下,您错了
fredoverflow 2014年

3
莫里斯,真是太好了!当有很多事情要做时,我碰巧会丢失一些简单的东西:)
sberezin 2014年

6
这种计算策略内爆时,双方都包装类,new Boolean(true) != new Boolean(true)给出了true
VlastimilOvčáčík17年

74

Java具有逻辑AND运算符。
Java具有逻辑或运算符。

错误。

Java有

  • 两个逻辑AND运算符:正常AND为&和短路AND为&&,和
  • 两个逻辑OR运算符:普通OR为| 并且短路OR为||。

XOR仅以^形式存在,因为不可能进行短路评估。


2
有趣的评论。有记录吗?
user666412 2013年

1
我认为&和| 不是短路,因为它们是按位运算符。实际上,不可能将它们短路。
奎尔斯托夫·贾布洛夫斯基(KrzysztofJabłoński)'13年

3
@KrzysztofJabłoński它们是数字的按位运算符,但在这里我们谈论的是布尔表达式。
starblue

3
@ user666412是,在Java语言规范中(还有其他地方?)。
starblue

18
如果它具有2个AND运算符和2个OR运算符,则语句“ Java具有逻辑AND运算符”和“ Java具有逻辑OR运算符”是正确的。根据定义,如果您有2件东西,那么您也有1件。
RyanfaeScotland

31

也许你误解了差异之间&&&||| 快捷运营商的目的&&,并||是第一个操作数的值可以决定结果,因此并不需要第二个操作数并进行评估。

如果第二个操作数将导致错误,则这特别有用。例如

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

但是,使用XOR时,您始终必须评估第二个操作数才能得到结果,因此唯一有意义的操作是^



9

这是因为运算符重载是他们特意排除在语言之外的。他们用字符串连接“欺骗”了一点,但是除此之外,这种功能不存在。

(免责声明:我还没有使用过Java的最后2个主要版本,所以如果现在使用它,我会感到非常惊讶)


5
请记住,您也无法在C ++中定义新的运算符。您所能做的就是为旧的赋予新的含义。
David Thornley,

7

Java中唯一的运算符重载是字符串上的+(JLS 15.18.1字符串串联运算符+)。

社区已被划分为3年了,其中1/3不需要,1/3不需要,1/3不在乎。

您可以使用unicode创建作为符号的方法名称...因此,如果您要使用符号,则可以执行myVal = x。$(y);。其中$是符号而x不是原始符号...但是在某些编辑器中这将是不可靠的,并且由于无法在原始符号上执行而受到限制。


7

下面的代码:

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

是多余的。

为什么不写:

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

另外,正如javashlook 所说,已经有^运算符。

!=^工作相同*布尔操作数(你的情况),但对于不同的整数操作数。

*注意:
1.它们对于boolean(原始Boolean类型)操作相同,但对于(对象类型)操作数则无效。由于Boolean(对象类型)值可以具有value null。并且!=将返回,false或者true当其一个或两个操作数为时返回null,而在这种情况下^将抛出NullPointerException
2.尽管它们的工作原理相同,但是它们具有不同的优先级,例如,当与&a & b != c & d一起使用时,将被视为a & (b != c) & d,而a & b ^ c & d将被视为(a & b) ^ (c & d)(offtopic:ouch,C样式优先级表很烂)。


1
对于布尔值,我喜欢!=
GKalnytskyi

1
@GKalnytskyi的Boolean!=工作不正确。对于boolean值来说还可以。
vadipp

2
!= ^和不工作相同布尔操作数。由于优先级,“ false&false!= true”与“ false&false ^ true”将得到不同的结果。
艾伯特·亨德里克斯

1
@AlbertHendriks,我最好说一下它们的工作原理相同,但是优先级不同(尽管这只是术语问题)。
萨沙

6

这是Java的var arg XOR方法...

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

请享用


感觉它会有一些非常奇怪的行为。例如,XOR(true,true,true)返回true,这似乎与您从称为的方法中所期望的不一样XOR。我的预期行为是它总是返回false(这当然没有用)
Richard Tingle

4

逻辑异或在Java中称为!=^如果您想混淆朋友,也可以使用。


2

您可以使用Xtend(中缀运算符和运算符重载)来重载运算符并“停留”在Java上


注意Xtend不允许您覆盖插入符^;您必须使用bool_1.xor(bool_2)。奇怪的是,解析器甚至不允许您使用插入符号。您必须使用xor布尔值和bitwiseXor整数。您当然可以使另一个运算符重载,但这将非常令人困惑。
开尔文

2

您要的东西没有多大意义。除非我不正确,否则建议您要使用AND或OR的方式使用XOR来执行逻辑运算。您提供的代码实际上显示了我要参考的内容:

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

您的函数具有布尔输入,并且对布尔使用按位XOR运算时,结果与您提供的代码相同。换句话说,当比较单个位(布尔值)或比较较大值的单个位时,按位XOR已经很有效。为了说明这一点,就二进制值而言,任何非零值均为TRUE,而只有ZERO为false。

因此,要以与应用逻辑逻辑AND相同的方式应用XOR,您要么只使用只有一位的二进制值(给出相同的结果和效率),要么必须将二进制值作为一个整体而不是每个位进行评估。换句话说,表达式(010 ^^ 110)= FALSE而不是(010 ^^ 110)=100。这将删除操作中的大部分语义,并表示您不应该使用的逻辑测试。


1

A和B必须是布尔值才能使!=与xor相同,以便真值表看起来相同。您也可以使用!(A == B)大声笑。


1

我正在使用非常受欢迎的类“ org.apache.commons.lang.BooleanUtils”

此方法已经过许多用户的测试,很安全。玩得开心。用法:

boolean result =BooleanUtils.xor(new boolean[]{true,false});

0

因为布尔数据类型像整数一样存储,所以与布尔值一起使用时,位运算符^的功能类似于XOR操作。

//©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
            */
        }
    }

0

这是一个例子:

给定2个int值,如果一个为负且一个为正,则返回true。除非参数“ negative”为true,否则仅当两个参数均为负时才返回true。

    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);
    }

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.