Java中的快捷方式“or-assignment”(| =)运算符

我在Java中做了很长时间的比较,我想知道它们中的一个或多个是否正确。 比较的string很长,很难阅读,所以我把它分解为可读性,并自动去使用快捷键运算符|=而不是negativeValue = negativeValue || boolean negativeValue = negativeValue || boolean

 boolean negativeValue = false; negativeValue |= (defaultStock < 0); negativeValue |= (defaultWholesale < 0); negativeValue |= (defaultRetail < 0); negativeValue |= (defaultDelivery < 0); 

如果任何默认的<something>值为negativeValue ,我预计negativeValue为true。 这有效吗? 它会做我所期望的吗? 我看不到它在Sun网站或者stackoverflow上提到过,但是Eclipse似乎没有问题,代码编译和运行。


同样,如果我想执行几个逻辑交集,我可以使用&=而不是&&

|=是布尔逻辑运算符|的复合赋值运算符( JLS 15.26.2 ) ( JLS 15.22.2 ); 不要与条件或||混淆 ( JLS 15.24 )。 还有&=^=对应于布尔逻辑&^的复合赋值版本。

换句话说,对于boolean b1, b2 ,这两个是等价的:

  b1 |= b2; b1 = b1 | b2; 

逻辑运算符( &| )与条件对应( &&|| )的区别在于前者不是“shortcircuit”。 后者呢。 那是:

  • &| 总是评估两个操作数
  • &&|| 有条件地评估正确的操作数; 只有当它的值可能影响二进制运算的结果时,右操作数才被评估。 这意味着右边的操作数在下列情况下不被评估:
    • &&的左操作数评估为false
      • (因为不pipe正确的操作数如何评估,整个expression式都是false
    • ||的左操作数 评估为true
      • (因为不pipe操作数是true ,整个expression式都是true

所以回到你原来的问题,是的,这个构造是有效的,而|=并不完全等同于=||快捷方式 ,它确实计算你想要的。 由于您使用的|=运算符的右侧是一个简单的整数比较操作,因此| 不短路是微不足道的。

有些情况下,当需要短路或甚至需要,但你的情况不是其中之一。

不幸的是,与其他一些语言不同,Java没有&&=||=为什么Java不具有条件语言和条件语言或运算符的复合赋值版本呢? (&& =,|| =)

这不是“快捷”(或短路)运营商的方式 和(&)是(如果他们已经知道基于LHS的结果,他们不会评估RHS),但是在工作方面它会做你想要的。

作为差异的一个例子,如果text为null,那么这个代码就可以了:

 boolean nullOrEmpty = text == null || text.equals("") 

而这不会:

 boolean nullOrEmpty = false; nullOrEmpty |= text == null; nullOrEmpty |= text.equals(""); // Throws exception if text is null 

(显然你可以为那个特定的情况做"".equals(text) – 我只是试图说明原理。)

虽然这可能是你的问题矫枉过正,但番石榴图书馆有一些很好的语法与Predicate s和Predicate评估或/和Predicate s。

实质上,比较转换成对象,打包成一个集合,然后迭代。 对于谓词,第一个真正的命中从迭代返回,反之亦然。

如果是关于可读性,我已经从testing逻辑中获得了分离testing数据的概念。 代码示例:

 // declare data DataType [] dataToTest = new DataType[] { defaultStock, defaultWholesale, defaultRetail, defaultDelivery } // define logic boolean checkIfAnyNegative(DataType [] data) { boolean negativeValue = false; int i = 0; while (!negativeValue && i < data.length) { negativeValue = data[i++] < 0; } return negativeValue; } 

代码看起来更详细和不言自明。 您甚至可以在方法调用中创build一个数组,如下所示:

 checkIfAnyNegative(new DataType[] { defaultStock, defaultWholesale, defaultRetail, defaultDelivery }); 

它比“比较string”更具可读性,并且具有短路(以数组分配和方法调用为代价)的性能优势。

编辑:通过使用可变参数可以简单地实现更多的可读性:

方法签名将是:

 boolean checkIfAnyNegative(DataType ... data) 

电话可能是这样的:

 checkIfAnyNegative( defaultStock, defaultWholesale, defaultRetail, defaultDelivery ); 

你可以只有一个声明。 用多行表示,它几乎完全像你的示例代码,只是不太必要:

 boolean negativeValue = defaultStock < 0 | defaultWholesale < 0 | defaultRetail < 0 | defaultDelivery < 0; 

对于最简单的expression式,使用| 可以比||更快 因为尽pipe它避免了进行比较,但意味着隐式地使用一个分支,而且可能要贵很多倍。

 List<Integer> params = Arrays.asList (defaultStock, defaultWholesale, defaultRetail, defaultDelivery); int minParam = Collections.min (params); negativeValue = minParam < 0; 

|| 逻辑布尔OR
| 按位或

| =按位包含的OR和赋值运算符

为什么| =不是shortcircit的原因是因为它执行的是或不是逻辑OR。 也就是说:


 C | = 2与C = C |相同  2

Java运算符教程