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)); + } }