1. 概述

在编程中,有些任务看似简单,比如检查两个布尔值是否相等。虽然听起来微不足道,但实现方式有多种,每种方法在可读性、功能性和边缘情况处理上都有独特之处。

本文将探讨如何检查布尔值之间的相等性,以及每种方法的适用场景。

2. 检查布尔值相等性的方法

有多种方法可以检查相等性,每种方法都有其细微差别和最佳使用场景。理解这些方法有助于我们编写更清晰、更安全、更高效的代码,尤其是在处理对象引用、处理null值或在更复杂的表达式中集成比较时。

本节将探讨检查两个布尔值是否相等的各种方法。

2.1 快速直接比较

检查两个布尔值是否相等的最简单直观的方法是使用 == 操作符:

@Test
void givenPrimitiveBooleans_whenUsingDirectComparison_thenCompare() {
    boolean a = true;
    boolean b = true;
    assertTrue(a == b, 
      "直接比较基本类型布尔值,当两者相同时应为true");

    a = true;
    b = false;
    assertFalse(a == b, 
      "直接比较基本类型布尔值,当两者不同时应为false");
}

在这个例子中,如果 ab 具有相同的布尔值,结果为 true,否则为 false。这种方法适用于基本类型布尔值(truefalse),并且在我们确定两个值都非空且为 boolean 类型时是理想选择。
Java 的 == 操作符自然适用于基本类型(包括 boolean),因为它检查的是值相等性而非引用相等性。它也很高效,因为直接比较值。 这种方法清晰且性能高,适合简单检查,是大多数情况下的首选。
然而,当处理 Boolean 对象而非基本类型 boolean 值时,情况就不同了。下一节将专门讨论这个问题。

2.2 使用 equals() 方法比较 Boolean 对象

当比较 Boolean 对象(Java 中 boolean 的包装类)时,使用 == 可能不会得到我们期望的结果。**Boolean 是一个对象,因此使用 == 检查的是引用相等性而非值相等性。为了确保比较的是值而不是引用,equals() 方法是更好的选择:**

@Test
void givenBooleans_whenUsingEqualsMethodWithBooleanObjects_thenCompare() {
    Boolean a = Boolean.TRUE;
    Boolean b = Boolean.TRUE;
    assertTrue(a.equals(b), 
      "在Boolean对象上使用equals(),当两者值相同时应为true");

    a = Boolean.TRUE;
    b = Boolean.FALSE;
    assertFalse(a.equals(b), 
      "在Boolean对象上使用equals(),当值不同时应为false");
}

在这段代码中,a.equals(b) 检查底层的布尔值是否相同,无论 ab 是否是不同的 Boolean 实例。
那么,为什么不在 Boolean 对象上使用 == 呢?

考虑以下代码:

@Test
void givenBooleansTypes_whenUsingDirectOperator_thenCompare() {
    Boolean a = Boolean.TRUE;
    Boolean b = new Boolean(true);
    assertFalse(a == b, 
      "在不同布尔对象上使用==,当值不同时应为false");
}

尽管 ab 的值都是 true,但使用 == 返回 false,因为 ab 是不同的 Boolean 实例。使用 equals() 确保比较基于实际值(truefalse)而非对象引用,这在处理可空值时特别有用。
我们在 Boolean 对象上使用 equals() 是为了避免对象引用比较导致的意外行为。

2.3 使用逻辑异或(XOR)

我们可以考虑使用逻辑异或(XOR)操作符 ^ 来实现一个更有创意的解决方案。两个布尔值的异或结果在值不同时返回 true,在值相同时返回 false
通过否定结果,我们可以检查两个布尔值是否相等:

@Test
void givenBooleans_whenUsingXORApproach_thenCompare() {
    boolean a = true;
    boolean b = true;
    assertTrue(!(a ^ b), 
      "XOR方法在两者值相同时应返回true");

    a = true;
    b = false;
    assertFalse(!(a ^ b), 
      "XOR方法在值不同时应返回false");
}

这个方法通过检查两个值是否同为 true 或同为 false 来工作。虽然这种方法不太常见且可读性稍差,但它很高效,在可能已经使用XOR逻辑的场景中很有用。

使用XOR可能感觉不太直观,因此它最适合XOR逻辑本身就有意义或性能至关重要的场景。如果代码可读性是优先考虑的,那么 == 操作符可能是更好的选择。

2.4 使用 Boolean.compare()

Java 提供了一个静态方法 Boolean.compare() 专门用于比较两个布尔值。该方法在值相等时返回 0,第一个为 true 且第二个为 false 时返回 1,第一个为 false 且第二个为 true 时返回 -1

@Test
void givenBooleans_whenUsingBooleanCompare_thenCompare() {
    boolean a = true;
    boolean b = true;
    assertTrue(Boolean.compare(a, b) == 0, 
      "Boolean.compare()在两者值相同时应返回0");

    a = true;
    b = false;
    assertFalse(Boolean.compare(a, b) == 0, 
      "Boolean.compare()在值不同时应返回非零");
}

这种方法在我们处理排序或需要不仅仅是相等性检查时很有用。通过检查 Boolean.compare(a, b) == 0,我们可以确认两个布尔值同为 true 或同为 false

2.5 使用 Objects.equals() 避免 NullPointerException

如果我们比较可能为 nullBoolean 对象,使用 java.util.Objects 包中的 Objects.equals() 是一个不错的选择。它能优雅地处理 null 值:当两者都为 null 时返回 true,当只有一个为 null 时返回 false

@Test
void givenBooleans_whenUsingObjectsEqualsForNullableBooleans_thenCompare() {
    Boolean a = null;
    Boolean b = null;
    assertTrue(Objects.equals(a, b), 
      "Objects.equals()在两个Boolean对象都为null时应返回true");

    a = Boolean.TRUE;
    b = null;
    assertFalse(Objects.equals(a, b), 
      "Objects.equals()在其中一个Boolean为null时应返回false");

    a = Boolean.TRUE;
    b = Boolean.TRUE;
    assertTrue(Objects.equals(a, b), 
      "Objects.equals()在两个Boolean值相同时应返回true");

    a = Boolean.TRUE;
    b = Boolean.FALSE;
    assertFalse(Objects.equals(a, b), 
      "Objects.equals()在Boolean值不同时应返回false");
}

这种方法避免了 NullPointerException 并检查值相等性。 它在处理可空数据或比较可能未初始化的值时特别有用。

3. 方法比较

让我们对讨论过的所有方法进行一次比较。

方法 使用场景 注意事项
== 简单直接比较基本类型 boolean 快速直接;避免用于 Boolean 对象
equals() Boolean 对象比较 对于非基本类型,为避免引用相等性问题,首选此方法
XOR (^) 创意选项,不常用 高效但可读性差;在XOR逻辑合适时使用
Boolean.compare() 详细比较或排序需求 相等时返回0;在排序中有用
Objects.equals() 处理可能为null的值 安全处理可空的Boolean对象

4. 总结

在本文中,我们看到检查布尔值之间的相等性可以很简单但方法多样,每种方法都有其独特优势。对于基本的直接比较,== 在基本类型上效果最好,而 equals()Boolean 对象上确保可靠结果。XOR、Boolean.compare()Objects.equals() 等方法为特殊需求增加了灵活性,例如处理null或在复杂逻辑中集成比较。

选择正确的方法有助于使我们的代码更具可读性、安全性和针对性,确保布尔比较的清晰和正确性。
一如既往,本文中展示的代码可以在 GitHub 上获取。


原始标题:How to Check if Two Boolean Values Are Equal | Baeldung