用 XOR 取反布尔表达式
negation of boolean expressions with XOR
我有这个:
// returns true if both are equal (independent of scale) and also checks against null
public static boolean isEqual(BigDecimal val1, BigDecimal val2) {
// 1. check: both will be null or both will be non-null.
if (val1 != null ^ val2 != null) return false;
// 2. check: if not null, then compare if both are equal
return !(val2 != null && val1.compareTo(val2) != 0);
}
我想将布尔表达式合并为一个。所以我用这个:
public static boolean isEqual(BigDecimal val1, BigDecimal val2) {
return !(val1 != null ^ val2 != null) && !(val2 != null && val1.compareTo(val2) != 0);
}
但是,我担心这是否正确。这个对吗?这会是 simplified/shorten 吗?
在答案的帮助下,缩短的解决方案是:
// returns true, if both are null or both are equal
// (independent of their numbers scales)
public static boolean isEqual(BigDecimal val1, BigDecimal val2) {
return val1 == null ? val2 == null : val2 != null && val1.compareTo(val2) == 0;
}
您可以使用 Comparator.nullsFirst (or Comparator.nullsLast):
public static boolean isEqual(BigDecimal val1, BigDecimal val2) {
return Comparator.nullsFirst(BigDecimal::compareTo).compare(val1, val2) == 0;
}
示例:
System.out.println(isEqual(null, null));
System.out.println(isEqual(null, new BigDecimal(1.0)));
System.out.println(isEqual(new BigDecimal(1.0), null));
System.out.println(isEqual(new BigDecimal(1.0), new BigDecimal(1.0)));
输出
true
false
false
true
使用 ^
作为逻辑 XOR 运算符是非常不寻常的。它有效,但为了可读性,我会避免使用它。 !=
是一个很好的替代品。
return !((val1 != null) != (val2 != null)) && !(val2 != null && val1.compareTo(val2) != 0);
现在你可以用==
代替双重否定。不错
return ((val1 != null) == (val2 != null)) && !(val2 != null && val1.compareTo(val2) != 0);
您还可以通过 De Morgan's laws:
分发剩余的 !
return ((val1 != null) == (val2 != null)) && (val2 == null || val1.compareTo(val2) == 0);
好多了,但老实说我还是觉得不方便。即使不是单行语句,我也会选择更直接的东西:
if (val1 == null) {
return val2 == null;
}
else {
return val2 != null && val1.compareTo(val2) == 0;
}
您可以使用三元运算符代替 if
/else
。根据个人喜好,您会发现更具可读性:
return val1 == null
? val2 == null
: val2 != null && val1.compareTo(val2) == 0;
您提到您需要使用 compareTo()
。对于可能阅读此答案的其他人,如果您不必使用 compareTo()
,我会改用 equals()
。
if (val1 == null) {
return val2 == null;
}
else {
return val1.equals(val2);
}
那么,碰巧的是,您甚至根本不需要编写此方法。内置的 Objects.equals()
方法正是这样做的:如果两个对象相等,或者它们都为空,则 returns 为真。
如果规模不是问题,我会在这里使用三元,并利用 Object#equals
为 null
返回 false
:
//Basically Objects#equals at this point
public static boolean isEqual(BigDecimal val1, BigDecimal val2) {
return val1 == null ? val2 == null : val1.equals(val2);
}
因此在每种情况下:
[1: null, 2: null]: true
[1: null, 2: num]: false
[1: num, 2: null]: false
[1: num, 2: num]: Object#equals
然而,正如您所指出的,您也想在不考虑缩放比例的情况下进行比较。所以我们必须包括另一个空检查,因为如果你通过 null
:
#compareTo
抛出 NPE
public static boolean isEqual(BigDecimal val1, BigDecimal val2) {
return val1 == null
? val2 == null
: val2 != null && val1.compareTo(val2) == 0;
}
因此在每种情况下(再次):
[1: null, 2: null]: true
[1: null, 2: num]: false
[1: num, 2: null]: false
[1: num, 2: num]: BigDecimal#compareTo
我会发现它更具可读性,但它仍然有点笨拙。在这一点上,一个写得很好且简洁的评论(或者,根据其他答案分行)可能比重写代码对你更好。
我有这个:
// returns true if both are equal (independent of scale) and also checks against null
public static boolean isEqual(BigDecimal val1, BigDecimal val2) {
// 1. check: both will be null or both will be non-null.
if (val1 != null ^ val2 != null) return false;
// 2. check: if not null, then compare if both are equal
return !(val2 != null && val1.compareTo(val2) != 0);
}
我想将布尔表达式合并为一个。所以我用这个:
public static boolean isEqual(BigDecimal val1, BigDecimal val2) {
return !(val1 != null ^ val2 != null) && !(val2 != null && val1.compareTo(val2) != 0);
}
但是,我担心这是否正确。这个对吗?这会是 simplified/shorten 吗?
在答案的帮助下,缩短的解决方案是:
// returns true, if both are null or both are equal
// (independent of their numbers scales)
public static boolean isEqual(BigDecimal val1, BigDecimal val2) {
return val1 == null ? val2 == null : val2 != null && val1.compareTo(val2) == 0;
}
您可以使用 Comparator.nullsFirst (or Comparator.nullsLast):
public static boolean isEqual(BigDecimal val1, BigDecimal val2) {
return Comparator.nullsFirst(BigDecimal::compareTo).compare(val1, val2) == 0;
}
示例:
System.out.println(isEqual(null, null));
System.out.println(isEqual(null, new BigDecimal(1.0)));
System.out.println(isEqual(new BigDecimal(1.0), null));
System.out.println(isEqual(new BigDecimal(1.0), new BigDecimal(1.0)));
输出
true
false
false
true
使用 ^
作为逻辑 XOR 运算符是非常不寻常的。它有效,但为了可读性,我会避免使用它。 !=
是一个很好的替代品。
return !((val1 != null) != (val2 != null)) && !(val2 != null && val1.compareTo(val2) != 0);
现在你可以用==
代替双重否定。不错
return ((val1 != null) == (val2 != null)) && !(val2 != null && val1.compareTo(val2) != 0);
您还可以通过 De Morgan's laws:
分发剩余的!
return ((val1 != null) == (val2 != null)) && (val2 == null || val1.compareTo(val2) == 0);
好多了,但老实说我还是觉得不方便。即使不是单行语句,我也会选择更直接的东西:
if (val1 == null) {
return val2 == null;
}
else {
return val2 != null && val1.compareTo(val2) == 0;
}
您可以使用三元运算符代替 if
/else
。根据个人喜好,您会发现更具可读性:
return val1 == null
? val2 == null
: val2 != null && val1.compareTo(val2) == 0;
您提到您需要使用 compareTo()
。对于可能阅读此答案的其他人,如果您不必使用 compareTo()
,我会改用 equals()
。
if (val1 == null) {
return val2 == null;
}
else {
return val1.equals(val2);
}
那么,碰巧的是,您甚至根本不需要编写此方法。内置的 Objects.equals()
方法正是这样做的:如果两个对象相等,或者它们都为空,则 returns 为真。
如果规模不是问题,我会在这里使用三元,并利用 Object#equals
为 null
返回 false
:
//Basically Objects#equals at this point
public static boolean isEqual(BigDecimal val1, BigDecimal val2) {
return val1 == null ? val2 == null : val1.equals(val2);
}
因此在每种情况下:
[1: null, 2: null]: true
[1: null, 2: num]: false
[1: num, 2: null]: false
[1: num, 2: num]: Object#equals
然而,正如您所指出的,您也想在不考虑缩放比例的情况下进行比较。所以我们必须包括另一个空检查,因为如果你通过 null
:
#compareTo
抛出 NPE
public static boolean isEqual(BigDecimal val1, BigDecimal val2) {
return val1 == null
? val2 == null
: val2 != null && val1.compareTo(val2) == 0;
}
因此在每种情况下(再次):
[1: null, 2: null]: true
[1: null, 2: num]: false
[1: num, 2: null]: false
[1: num, 2: num]: BigDecimal#compareTo
我会发现它更具可读性,但它仍然有点笨拙。在这一点上,一个写得很好且简洁的评论(或者,根据其他答案分行)可能比重写代码对你更好。