Merge pull request #4218 from yangfeng123456/fix-xor-semantics

feat(BooleanUtil): 新增 exactlyOneTrue 方法用于互斥条件校验
This commit is contained in:
Golden Looly
2026-01-22 11:09:06 +08:00
committed by GitHub
2 changed files with 52 additions and 1 deletions

View File

@@ -445,6 +445,10 @@ public class BooleanUtil {
/**
* 对Boolean数组取异或
* 当前实现的语义为:当数组中 true 的数量为奇数时返回 true数量为偶数时返回 false。
*
* 注意:该方法并不是判断“是否恰好只有一个 true”
* 不适用于互斥条件校验(例如:多个条件只能有一个成立的场景)。
*
* <pre>
* BooleanUtil.xor(true, true) = false
@@ -453,8 +457,10 @@ public class BooleanUtil {
* BooleanUtil.xor(true, true) = false
* BooleanUtil.xor(false, false) = false
* BooleanUtil.xor(true, false) = true
* BooleanUtil.xor(true, true, true) = true
* BooleanUtil.xor(true, true, false) = false
* </pre>
*
* 如需判断“是否恰好只有一个 true”请使用 {@link #exactlyOneTrue(boolean...)}。
* @param array {@code boolean}数组
* @return 如果异或计算为true返回 {@code true}
*/
@@ -471,6 +477,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 (boolean b : array) {
if (b && ++count > 1) {
return false;
}
}
return count == 1;
}
/**
* 对Boolean数组取异或
*

View File

@@ -106,4 +106,24 @@ public class BooleanUtilTest {
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));
}
}