【问题标题】:Creating a "logical exclusive or" operator in Java在 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
  • 它叫!=,还有一个逻辑异或叫==

标签: java operators xor


【解决方案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 时,!= 将返回falsetrue,而在这种情况下^ 将抛出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;
                      }
                      

                      【讨论】:

                        猜你喜欢
                        • 2010-12-08
                        • 1970-01-01
                        • 2014-12-10
                        • 2011-08-25
                        • 1970-01-01
                        • 2019-08-03
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多