在 Java 中创建“逻辑异或”运算符
Posted
技术标签:
【中文标题】在 Java 中创建“逻辑异或”运算符【英文标题】:Creating a "logical exclusive or" operator in Java 【发布时间】:2010-10-18 02:52:13 【问题描述】:观察:
Java 有一个逻辑 AND 运算符。 Java 有一个逻辑 OR 运算符。 Java 有一个逻辑 NOT 运算符。
问题:
Java 没有逻辑 XOR 运算符 according to sun。我想定义一个。
方法定义:
作为一个方法,简单定义如下:
public static boolean logicalXOR(boolean x, boolean y)
return ( ( x || y ) && ! ( x && y ) );
方法调用:
该方法的调用方式如下:
boolean myVal = logicalXOR(x, y);
运算符用法:
我更希望有一个运算符,用法如下:
boolean myVal = x ^^ y;
问题:
我找不到任何关于如何在 Java 中定义新运算符的信息。我应该从哪里开始?
【问题讨论】:
什么?您提供的链接内容为“按位异或” 您是否想知道是否可以像在 C++ 中一样在 Java 中定义运算符? 看来你误解了&和&&的区别。两者都是逻辑运算符(在布尔值上)。 Starblue 的回答涵盖的范围更广。 仅仅因为它不在教程中,并不意味着Java没有它 - 教程并不(总是)完整。见Java Language Specification 15.22.2 它叫!=
,还有一个逻辑异或叫==
【参考方案1】:
这是因为运算符重载是他们特意从语言中遗漏的东西。他们用字符串连接“欺骗”了一点,但除此之外,这样的功能不存在。
(免责声明:我没有使用过 java 的最后两个主要版本,所以如果它现在发布,我会感到非常惊讶)
【讨论】:
请记住,您也不能在 C++ 中定义新的运算符。你所能做的就是给旧的赋予新的意义。【参考方案2】:Java确实有一个逻辑异或运算符,它是^(如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);
输出:
假 ^ 假 = 假 假 ^ 真 = 真 真 ^ 假 = 真 真 ^ 真 = 假【讨论】:
当我写我的帖子时,这也逃过了我的记忆,但我认为你可以使用 ^ 作为逻辑运算符(以及按位)。 ^ 不仅是位运算符。它也是一个逻辑运算符。 ^ 运算符已重载。它对整数类型或布尔类型进行操作。 +1 以获得很好的答案 javashlook。 Eddie,它没有比 JLS 第 15.22.2 节“布尔逻辑运算符 &、^ 和 |”更明确。 当然,答案是 && 和 ||将跳过计算表达式的第二部分和 & 和 |将始终评估表达式的两个部分(来自我对 JLS 的阅读)。根据定义,^^ 总是必须评估这两个部分,因此其行为与 ^ 相同。大概是为什么没有^^ @Eddie:那和 ^^ 看起来太像表情了。 也许这是一个语义问题,但是当涉及到 XOR 时,按位和逻辑会产生相同的结果。因此,不需要不同的运算符。 XOR 运算符的简化真值表是 X ^ !X = 1。您不能在 XOR 中短路输入,因为您必须确定输入是否不同。如果您知道实际 XOR 门的制作方法,则更容易理解。【参考方案3】:不是 x != y 吗?
【讨论】:
如果 x 和 y 是布尔值,那么 xor 和 != 的逻辑表是相同的: t,t => f ; t,f => t; f,t => t; f,f => f 莫里斯:啊,你简直让我大吃一惊!我怎么从来没有注意到这一点? @Milhous 你是说a != b != c
行不通,但a ^ b ^ c
行吗?在这种情况下,you are wrong.
莫里斯,太棒了!当有很多事情要做时,我碰巧忘记了简单的事情:)
当双方都是包装类时,这个方法会内爆,new Boolean(true) != new Boolean(true)
给出true
。【参考方案4】:
Java 中唯一的运算符重载是字符串上的 + (JLS 15.18.1 String Concatenation Operator +)。
社区多年来一直一分为三,1/3 不想要,1/3 想要,1/3 不关心。
您可以使用 unicode 来创建符号的方法名称...所以如果您有想要使用的符号,您可以执行 myVal = x.$(y);其中 $ 是符号,而 x 不是原语...但这在某些编辑器中会很狡猾,并且会受到限制,因为您无法在原语上执行此操作。
【讨论】:
【参考方案5】:Java 有一个逻辑 AND 运算符。 Java 有一个逻辑 OR 运算符。
错了。
Java 有
两个逻辑 AND 运算符:普通 AND 是 &,短路 AND 是 &&,和 两个逻辑或运算符:正常的 OR 是 |和短路或是||。XOR 仅作为 ^ 存在,因为不可能进行短路评估。
【讨论】:
有趣的评论。有记录吗? 我认为 & 和 |不是短路的,因为它们是按位运算符。事实上,不可能将它们短路。 @Krzysztof Jabłoński 它们是数字的按位运算符,但这里我们讨论的是布尔表达式。 @user666412 是的,在 Java 语言规范中(还有什么地方?)。 如果它有 2 个 AND 运算符和 2 个 OR 运算符,那么语句“Java 有一个逻辑 AND 运算符”和“Java 有一个逻辑 OR 运算符”没有错。根据定义,如果你有 2 个,那么你也有 1 个。【参考方案6】:也许你误解了&
和&&
、|
和||
之间的区别
快捷运算符&&
和||
的目的是第一个操作数的值可以确定结果,因此第二个操作数不需要计算。
如果第二个操作数会导致错误,这将特别有用。 例如
if (set == null || set.isEmpty())
// or
if (list != null && list.size() > 0)
但是,使用 XOR,您总是需要计算第二个操作数才能得到结果,因此唯一有意义的操作是 ^
。
【讨论】:
【参考方案7】:您可以使用Xtend (Infix Operators and Operator Overloading) 重载运算符并在 Java 上“停留”
【讨论】:
请注意,Xtend 不允许您覆盖插入符号^
;你必须使用bool_1.xor(bool_2)
。奇怪的是,解析器甚至不允许您使用插入符号;对于布尔值,您必须使用 xor
,对于整数必须使用 bitwiseXor
。当然,您可以重载另一个运算符,但这会让人很困惑。【参考方案8】:
这里是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(这当然没有帮助)【参考方案9】:
你可以写(a!=b)
这与a ^ b
的工作方式相同。
【讨论】:
【参考方案10】:由于布尔数据类型像整数一样存储,如果与布尔值一起使用,位运算符 ^ 的功能类似于 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
*/
【讨论】:
【参考方案11】:以下是您的代码:
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 said,已经有 ^
运算符。
!=
和 ^
对于布尔操作数(您的情况)的工作方式相同*,但对于整数操作数则不同。
* 备注:
1. 它们对于boolean
(原始类型)的工作方式相同,但对于Boolean
(对象类型)操作数不同。正如Boolean
(对象类型)值可以具有值null
。当!=
的一个或两个操作数为null
时,!=
将返回false
或true
,而在这种情况下^
将抛出NullPointerException
。
2.虽然它们的工作方式相同,但它们的优先级不同,例如与&
一起使用时:a & b != c & d
将被视为a & (b != c) & d
,而a & b ^ c & d
将被视为(a & b) ^ (c & d)
(题外话:哎呀,C 样式的优先级表很烂)。
【讨论】:
布尔值我喜欢!=
@GKalnytskyi for Boolean
值 !=
工作不正确。对于boolean
值,没关系。
!= 和 ^ 对于布尔操作数完全相同工作。由于优先级不同,“false & false != true”与“false & false ^ true”会得到不同的结果。
@AlbertHendriks,我最好说它们工作相同,但有不同的优先级(尽管这只是术语问题)。
【参考方案12】:
这是一个例子:
给定 2 个 int 值,如果一个是负数,一个是正数,则返回 true。除非参数“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);
【讨论】:
【参考方案13】:你所要求的没有多大意义。除非我不正确,否则您建议您要使用 XOR 以与 AND 和 OR 相同的方式执行逻辑运算。您提供的代码实际上显示了我所指的内容:
public static boolean logicalXOR(boolean x, boolean y)
return ( ( x || y ) && ! ( x && y ) );
您的函数具有布尔输入,当对布尔值使用按位异或时,结果与您提供的代码相同。换句话说,在比较单个位(布尔值)或比较较大值中的单个位时,按位异或已经很有效。把它放到上下文中,就二进制值而言,任何非零值都是 TRUE,只有 ZERO 是 false。
因此,要以与应用逻辑 AND 相同的方式应用 XOR,您要么只使用只有一位的二进制值(给出相同的结果和效率),要么必须将二进制值作为一个整体来评估,而不是每比特。换句话说,表达式 (010 ^^ 110) = FALSE 而不是 (010 ^^ 110) = 100。这将从操作中删除大部分语义含义,并表示您无论如何都不应该使用的逻辑测试。
【讨论】:
【参考方案14】:A 和 B 必须是布尔值才能使 != 与 xor 相同,以便真值表看起来相同。您也可以使用 !(A==B) 大声笑。
【讨论】:
【参考方案15】:我正在使用非常流行的类“org.apache.commons.lang.BooleanUtils”
这种方法已经过很多用户的测试并且安全。玩得开心。 用法:
boolean result =BooleanUtils.xor(new boolean[]true,false);
【讨论】:
最佳答案。谢谢!【参考方案16】:您需要切换到 Scala 来实现自己的运算符
pipe example
【讨论】:
【参考方案17】:Java 中的逻辑异或称为!=
。如果你想迷惑你的朋友,你也可以使用^
。
【讨论】:
【参考方案18】:这是一个使用 XOR(^) 的例子,来自 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++];
输出
0 0 1 1 1 0
【讨论】:
【参考方案19】:可以在java 8及以上使用流API实现
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;
【讨论】:
以上是关于在 Java 中创建“逻辑异或”运算符的主要内容,如果未能解决你的问题,请参考以下文章