首页 > 解决方案 > 用 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);
}

但是,我担心这是否正确。这个对吗?这可以简化/缩短吗?

在答案的帮助下,缩短的解决方案是:

// 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;
}

标签: javaequalitysimplify

解决方案


^用作逻辑 XOR 运算符是非常不寻常的。它有效,但为了便于阅读,我会避免使用它。!=是一个很好的替代品。

return !((val1 != null) != (val2 != null)) && !(val2 != null && val1.compareTo(val2) != 0);

现在您可以将双重否定替换为==. 好的。

return ((val1 != null) == (val2 != null)) && !(val2 != null && val1.compareTo(val2) != 0);

您还可以!通过德摩根定律分配剩余部分:

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()方法正是这样做的:如果两个对象相等,或者它们都为空,则返回 true。


推荐阅读