在Java中创建"逻辑独占或"运算符

ele*_*n81 265 java operators xor

观察:

Java有一个逻辑AND运算符.
Java有一个逻辑OR运算符.
Java有一个逻辑NOT运算符.

问题:

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

方法定义:

作为一种方法,它只是定义如下:

public static boolean logicalXOR(boolean x, boolean y) {
    return ( ( x || y ) && ! ( x && y ) );
}
Run Code Online (Sandbox Code Playgroud)


方法调用:

以下列方式调用此方法:

boolean myVal = logicalXOR(x, y);
Run Code Online (Sandbox Code Playgroud)


运营商用法:

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

boolean myVal = x ^^ y;
Run Code Online (Sandbox Code Playgroud)


题:

我找不到任何关于如何在Java中定义新运算符的内容.我应该从哪里开始?

jav*_*ook 674

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

false ^ false = false
false ^ true = true
true ^ false = true
true ^ true = false

  • ^不仅是一个按位运算符.它也是一个合乎逻辑的运算符.^运算符被重载.它对整数类型或布尔类型进行操作.+1为一个伟大的答案javashlook.Eddie,它没有比JLS Section 15.22.2,"布尔逻辑运算符&,^和|"更明确. (141认同)
  • 当然,答案是&&和|| 将跳过评估表达式的第二部分和&和| 将始终评估表达式的两个部分(从我读取的JLS).根据定义,^^总是必须评估两个部分,因此行为与^相同.可能为什么没有^^ (95认同)
  • @Eddie:那和^^看起来太像一个表情符号了. (80认同)
  • 当我写帖子时,这也逃过了我的记忆,但我认为你可以使用^作为逻辑运算符(以及按位). (5认同)
  • 也许这是语义问题,但是当谈到XOR时,按位和逻辑会产生相同的结果.因此,不需要不同的运营商.XOR运算符的简化真值表是X ^!X = 1.您不能在XOR中短路输入,因为您必须确定输入是否不同.如果您知道实际XOR门的制造,则更容易理解. (5认同)
  • @mmyers:查看OP刚刚编辑过的链接.在"学习Java语言"中,Sun列出了逻辑OR,按位OR,按位XOR,依此类推,但没有逻辑XOR.实际上,是的,有一个.但它不一致.为什么我们有&&和|| 但不是^^,而&,|,^可以以相同的方式使用 (2认同)
  • 顺便说一句:它可以用简单的 `a != b` 来代替 (2认同)

Mau*_*rry 299

不是x!= y?

  • 莫里斯:阿尔你只是吹了我的脑海!我怎么没注意到这个? (79认同)
  • @Milhous你是说'a!= b!= c`不起作用,但`a ^ b ^ c`会吗?在那种情况下,[你错了](https://ideone.com/8lQRmF). (8认同)
  • 如果x和y是布尔值,那么xor和!=的逻辑表是相同的:t,t => f; t,f => t; f,t => t; f,f => f (5认同)
  • 当双方都是包装类时,这个approch内爆,`new Boolean(true)!= new Boolean(true)`给出`true`. (5认同)
  • 莫里斯,真是太棒了!当有很多事情要做时,我突然想到失去简单的东西:) (3认同)
  • @Milhous你对'a ^ b ^ ... ^ z`的期望是什么?如果你只想在****变量为真时才能获得真实的结果,那么你会非常失望.如果真实变量的数量是**奇数**,则`^`和`!=`的链都返回true.要记住的事情. (3认同)
  • 这只适用于2个布尔值,而不是布尔值列表 (2认同)
  • @StijndeWitt不,它没有:^不适用于对象,而!=不适用. (2认同)

sta*_*lue 73

Java有一个逻辑AND运算符.
Java有一个逻辑OR运算符.

错误.

Java有

  • 两个逻辑AND运算符:正常AND和&和短路AND是&&,和
  • 两个逻辑OR运算符:正常OR是| 和短路OR是||.

XOR仅作为^存在,因为不可能进行短路评估.

  • 如果它有2个AND运算符和2个OR运算符,则语句'Java具有逻辑AND运算符'和'Java具有逻辑OR运算符'没有错.根据定义,如果你有2个东西,那么你也有1个. (16认同)
  • @KrzysztofJabłoński他们是数字上的按位运算符,但这里我们讨论的是布尔表达式. (3认同)
  • @ user666412是的,在Java语言规范中(还有其他地方?). (3认同)
  • 有趣的评论.有记录吗? (2认同)
  • 当有人回复一句话回复时,我不禁要认真对待! (2认同)

Pet*_*rey 31

也许您误解了&和之间的差异&&,|以及|| 快捷运算符的用途,&&并且||第一个操作数的值可以确定结果,因此不需要计算第二个操作数.

如果第二个操作数会导致错误,这尤其有用.例如

if (set == null || set.isEmpty())
// or
if (list != null && list.size() > 0)
Run Code Online (Sandbox Code Playgroud)

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


Shu*_*yey 20

你可以写 (a!=b)

这将起到同样的作用a ^ b.


Kev*_*son 9

这是因为运算符重载是他们特意故意忽略的语言.他们使用字符串连接"欺骗"了一些,但除此之外,这种功能并不存在.

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

  • 请记住,您也无法在C++中定义新的运算符.你所能做的只是给旧的意义. (5认同)

Tof*_*eer 7

Java中唯一的运算符重载是字符串上的+(JLS 15.18.1字符串连接运算符+).

社区已经分为3年,1/3不想要它,1/3想要它,1/3不关心.

您可以使用unicode创建符号的方法名称...因此,如果您有一个想要使用的符号,则可以执行myVal = x.$(y); 其中$是符号而x不是原始的...但是在某些编辑器中这将是狡猾的并且是限制性的,因为你不能在原语上做.


Sas*_*sha 7

以下代码:

public static boolean logicalXOR(boolean x, boolean y) {
    return ( ( x || y ) && ! ( x && y ) );
}
Run Code Online (Sandbox Code Playgroud)

是多余的.

为什么不写:

public static boolean logicalXOR(boolean x, boolean y) {
    return x != y;
}
Run Code Online (Sandbox Code Playgroud)

另外,正如javashlook 所说,已有^运营商.

!=并且^对于布尔操作数(您的情况)工作相同*,但对于整数操作数不同.

*注意:
1.它们boolean(原始类型)的工作方式相同,但不是Boolean(对象类型)操作数.作为Boolean(对象类型)值可以有值null.并且!=将返回falsetrue当它的一个或两个操作数都是null,而^将抛出NullPointerException这种情况.
2.虽然它们的工作方式相同,但它们具有不同的优先级,例如当用于&:a & b != c & d将被视为a & (b != c) & d,而a & b ^ c & d将被视为(a & b) ^ (c & d)(offtopic:ouch,C风格的优先级表很糟糕).

  • 对于布尔操作数,!=和^不能*相同*.由于优先级的原因,您将获得"false&false!= true"与"false&false ^ true"的不同结果. (2认同)

小智 6

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

public static boolean XOR(boolean... args) {
  boolean r = false;
  for (boolean b : args) {
    r = r ^ b;
  }
  return r;
}
Run Code Online (Sandbox Code Playgroud)

请享用


Dor*_*dus 6

Java 中的逻辑异或称为!=. ^如果你想迷惑你的朋友,你也可以使用。