diff --git a/hutool-core/src/main/java/cn/hutool/v7/core/util/BooleanUtil.java b/hutool-core/src/main/java/cn/hutool/v7/core/util/BooleanUtil.java index 9b7a28700a..27c0ff1975 100644 --- a/hutool-core/src/main/java/cn/hutool/v7/core/util/BooleanUtil.java +++ b/hutool-core/src/main/java/cn/hutool/v7/core/util/BooleanUtil.java @@ -471,6 +471,9 @@ public class BooleanUtil { /** * 对boolean数组取异或 + * 当前实现的语义为:当数组中 true 的数量为奇数时返回 true,数量为偶数时返回 false。 + * 注意:该方法并不是判断“是否恰好只有一个 true”, + * 不适用于互斥条件校验(例如:多个条件只能有一个成立的场景)。 * *
* BooleanUtil.xor(true, true) = false
@@ -481,6 +484,7 @@ public class BooleanUtil {
* BooleanUtil.xor(true, true, false) = false
* BooleanUtil.xor(true, false, false) = true
*
+ * 如需判断“是否恰好只有一个 true”,请使用 {@link #exactlyOneTrue(boolean...)}。
*
* @param array {@code boolean}数组
* @return 如果异或计算为true返回 {@code true}
@@ -530,6 +534,31 @@ public class BooleanUtil {
return result;
}
+ /**
+ * 判断 boolean 数组中是否 恰好只有一个 元素为 true。
+ * 常用于互斥条件校验场景,例如:
+ * 多个角色只能同时存在一个
+ * 多个条件只能命中一个分支
+ * 与 {@link #xor(boolean...)} 不同,
+ * 本方法在出现多个 true 时会直接返回 false。
+ *
+ * @param array boolean 数组
+ * @return 当且仅当数组中恰好只有一个 true 时返回 true
+ */
+ public static boolean exactlyOneTrue(final boolean... array) {
+ if (ArrayUtil.isEmpty(array)) {
+ throw new IllegalArgumentException("The Array must not be empty");
+ }
+
+ int count = 0;
+ for (final boolean b : array) {
+ if (b && ++count > 1) {
+ return false;
+ }
+ }
+ return count == 1;
+ }
+
/**
* 给定类是否为Boolean或者boolean
*
diff --git a/hutool-core/src/test/java/cn/hutool/v7/core/util/BooleanUtilTest.java b/hutool-core/src/test/java/cn/hutool/v7/core/util/BooleanUtilTest.java
index e0ea6eb12f..0183a22349 100644
--- a/hutool-core/src/test/java/cn/hutool/v7/core/util/BooleanUtilTest.java
+++ b/hutool-core/src/test/java/cn/hutool/v7/core/util/BooleanUtilTest.java
@@ -148,4 +148,24 @@ public class BooleanUtilTest {
final Boolean result = BooleanUtil.andOfWrap(boolean1, boolean2);
assertFalse(result);
}
+
+ @Test
+ public void testXorSemantics() {
+ // xor 的实际语义:true 的数量为奇数
+ assertTrue(BooleanUtil.xor(true, true, true));
+ assertFalse(BooleanUtil.xor(true, true));
+ }
+
+ @Test
+ public void testExactlyOneTrue() {
+ // 恰好只有一个 true
+ assertTrue(BooleanUtil.exactlyOneTrue(true, false, false));
+
+ // 多个 true,不符合互斥语义
+ assertFalse(BooleanUtil.exactlyOneTrue(true, true, false));
+ assertFalse(BooleanUtil.exactlyOneTrue(true, true, true));
+
+ // 没有 true
+ assertFalse(BooleanUtil.exactlyOneTrue(false, false, false));
+ }
}