LANG-921 - BooleanUtils.xor(boolean...) produces wrong results
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@1532476 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
a01e450694
commit
aadbea734d
|
@ -22,6 +22,7 @@
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<release version="3.2" date="TBA" description="Next release">
|
<release version="3.2" date="TBA" description="Next release">
|
||||||
|
<action issue="LANG-921" type="fix" dev="britter">BooleanUtils.xor(boolean...) produces wrong results</action>
|
||||||
<action issue="LANG-910" type="update" due-to="Timur Yarosh">StringUtils.normalizeSpace now handles non-breaking spaces (Unicode 00A0)</action>
|
<action issue="LANG-910" type="update" due-to="Timur Yarosh">StringUtils.normalizeSpace now handles non-breaking spaces (Unicode 00A0)</action>
|
||||||
<action issue="LANG-804" type="update" dev="britter" due-to="Allon Mureinik">Redundant check for zero in HashCodeBuilder ctor</action>
|
<action issue="LANG-804" type="update" dev="britter" due-to="Allon Mureinik">Redundant check for zero in HashCodeBuilder ctor</action>
|
||||||
<action issue="LANG-893" type="add" dev="oheger" due-to="Woonsan Ko">StrSubstitutor now supports default values for variables</action>
|
<action issue="LANG-893" type="add" dev="oheger" due-to="Woonsan Ko">StrSubstitutor now supports default values for variables</action>
|
||||||
|
|
|
@ -1028,14 +1028,6 @@ public class BooleanUtils {
|
||||||
* BooleanUtils.xor(true, false) = true
|
* BooleanUtils.xor(true, false) = true
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* <p>Note that this method behaves different from using the binary XOR operator (^). Instead of combining the given
|
|
||||||
* booleans using the XOR operator from left to right, this method counts the appearances of true in the given
|
|
||||||
* array. It will only return true if exactly one boolean in the given array is true:</p>
|
|
||||||
* <pre>
|
|
||||||
* true ^ true ^ false ^ true = true
|
|
||||||
* BooleanUtils.xor(true, true, false, true) = false
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @param array an array of {@code boolean}s
|
* @param array an array of {@code boolean}s
|
||||||
* @return {@code true} if the xor is successful.
|
* @return {@code true} if the xor is successful.
|
||||||
* @throws IllegalArgumentException if {@code array} is {@code null}
|
* @throws IllegalArgumentException if {@code array} is {@code null}
|
||||||
|
@ -1050,22 +1042,13 @@ public class BooleanUtils {
|
||||||
throw new IllegalArgumentException("Array is empty");
|
throw new IllegalArgumentException("Array is empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loops through array, comparing each item
|
// false if the neutral element of the xor operator
|
||||||
int trueCount = 0;
|
boolean result = false;
|
||||||
for (final boolean element : array) {
|
for (final boolean element : array) {
|
||||||
// If item is true, and trueCount is < 1, increments count
|
result ^= element;
|
||||||
// Else, xor fails
|
|
||||||
if (element) {
|
|
||||||
if (trueCount < 1) {
|
|
||||||
trueCount++;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if there was exactly 1 true item
|
return result;
|
||||||
return trueCount == 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1077,9 +1060,6 @@ public class BooleanUtils {
|
||||||
* BooleanUtils.xor(new Boolean[] { Boolean.TRUE, Boolean.FALSE }) = Boolean.TRUE
|
* BooleanUtils.xor(new Boolean[] { Boolean.TRUE, Boolean.FALSE }) = Boolean.TRUE
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* <p>Note that this method behaves different from using the binary XOR operator (^). See
|
|
||||||
* {@link #xor(boolean...)}.</p>
|
|
||||||
*
|
|
||||||
* @param array an array of {@code Boolean}s
|
* @param array an array of {@code Boolean}s
|
||||||
* @return {@code true} if the xor is successful.
|
* @return {@code true} if the xor is successful.
|
||||||
* @throws IllegalArgumentException if {@code array} is {@code null}
|
* @throws IllegalArgumentException if {@code array} is {@code null}
|
||||||
|
|
|
@ -446,56 +446,68 @@ public class BooleanUtilsTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testXor_primitive_validInput_2items() {
|
public void testXor_primitive_validInput_2items() {
|
||||||
assertTrue(
|
assertEquals(
|
||||||
"True result for (true, true)",
|
"true ^ true",
|
||||||
! BooleanUtils.xor(new boolean[] { true, true }));
|
true ^ true ,
|
||||||
|
BooleanUtils.xor(new boolean[] { true, true }));
|
||||||
|
|
||||||
assertTrue(
|
assertEquals(
|
||||||
"True result for (false, false)",
|
"false ^ false",
|
||||||
! BooleanUtils.xor(new boolean[] { false, false }));
|
false ^ false,
|
||||||
|
BooleanUtils.xor(new boolean[] { false, false }));
|
||||||
|
|
||||||
assertTrue(
|
assertEquals(
|
||||||
"False result for (true, false)",
|
"true ^ false",
|
||||||
|
true ^ false,
|
||||||
BooleanUtils.xor(new boolean[] { true, false }));
|
BooleanUtils.xor(new boolean[] { true, false }));
|
||||||
|
|
||||||
assertTrue(
|
assertEquals(
|
||||||
"False result for (false, true)",
|
"false ^ true",
|
||||||
|
false ^ true,
|
||||||
BooleanUtils.xor(new boolean[] { false, true }));
|
BooleanUtils.xor(new boolean[] { false, true }));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testXor_primitive_validInput_3items() {
|
public void testXor_primitive_validInput_3items() {
|
||||||
assertTrue(
|
assertEquals(
|
||||||
"False result for (false, false, true)",
|
"false ^ false ^ false",
|
||||||
|
false ^ false ^ false,
|
||||||
|
BooleanUtils.xor(new boolean[] { false, false, false }));
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
"false ^ false ^ true",
|
||||||
|
false ^ false ^ true,
|
||||||
BooleanUtils.xor(new boolean[] { false, false, true }));
|
BooleanUtils.xor(new boolean[] { false, false, true }));
|
||||||
|
|
||||||
assertTrue(
|
assertEquals(
|
||||||
"False result for (false, true, false)",
|
"false ^ true ^ false",
|
||||||
|
false ^ true ^ false,
|
||||||
BooleanUtils.xor(new boolean[] { false, true, false }));
|
BooleanUtils.xor(new boolean[] { false, true, false }));
|
||||||
|
|
||||||
assertTrue(
|
assertEquals(
|
||||||
"False result for (true, false, false)",
|
"false ^ true ^ true",
|
||||||
|
false ^ true ^ true,
|
||||||
|
BooleanUtils.xor(new boolean[] { false, true, true }));
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
"true ^ false ^ false",
|
||||||
|
true ^ false ^ false,
|
||||||
BooleanUtils.xor(new boolean[] { true, false, false }));
|
BooleanUtils.xor(new boolean[] { true, false, false }));
|
||||||
|
|
||||||
assertTrue(
|
assertEquals(
|
||||||
"True result for (true, true, true)",
|
"true ^ false ^ true",
|
||||||
! BooleanUtils.xor(new boolean[] { true, true, true }));
|
true ^ false ^ true,
|
||||||
|
BooleanUtils.xor(new boolean[] { true, false, true }));
|
||||||
|
|
||||||
assertTrue(
|
assertEquals(
|
||||||
"True result for (false, false)",
|
"true ^ true ^ false",
|
||||||
! BooleanUtils.xor(new boolean[] { false, false, false }));
|
true ^ true ^ false,
|
||||||
|
BooleanUtils.xor(new boolean[] { true, true, false }));
|
||||||
|
|
||||||
assertTrue(
|
assertEquals(
|
||||||
"True result for (true, true, false)",
|
"true ^ true ^ true",
|
||||||
! BooleanUtils.xor(new boolean[] { true, true, false }));
|
true ^ true ^ true,
|
||||||
|
BooleanUtils.xor(new boolean[] { true, true, true }));
|
||||||
assertTrue(
|
|
||||||
"True result for (true, false, true)",
|
|
||||||
! BooleanUtils.xor(new boolean[] { true, false, true }));
|
|
||||||
|
|
||||||
assertTrue(
|
|
||||||
"False result for (false, true, true)",
|
|
||||||
! BooleanUtils.xor(new boolean[] { false, true, true }));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
@ -515,35 +527,50 @@ public class BooleanUtilsTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testXor_object_validInput_2items() {
|
public void testXor_object_validInput_2items() {
|
||||||
assertTrue(
|
assertEquals(
|
||||||
"True result for (true, true)",
|
"false ^ false",
|
||||||
! BooleanUtils
|
false ^ false,
|
||||||
.xor(new Boolean[] { Boolean.TRUE, Boolean.TRUE })
|
BooleanUtils
|
||||||
.booleanValue());
|
|
||||||
|
|
||||||
assertTrue(
|
|
||||||
"True result for (false, false)",
|
|
||||||
! BooleanUtils
|
|
||||||
.xor(new Boolean[] { Boolean.FALSE, Boolean.FALSE })
|
.xor(new Boolean[] { Boolean.FALSE, Boolean.FALSE })
|
||||||
.booleanValue());
|
.booleanValue());
|
||||||
|
|
||||||
assertTrue(
|
assertEquals(
|
||||||
"False result for (true, false)",
|
"false ^ true",
|
||||||
|
false ^ true,
|
||||||
|
BooleanUtils
|
||||||
|
.xor(new Boolean[] { Boolean.FALSE, Boolean.TRUE })
|
||||||
|
.booleanValue());
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
"true ^ false",
|
||||||
|
true ^ false,
|
||||||
BooleanUtils
|
BooleanUtils
|
||||||
.xor(new Boolean[] { Boolean.TRUE, Boolean.FALSE })
|
.xor(new Boolean[] { Boolean.TRUE, Boolean.FALSE })
|
||||||
.booleanValue());
|
.booleanValue());
|
||||||
|
|
||||||
assertTrue(
|
assertEquals(
|
||||||
"False result for (false, true)",
|
"true ^ true",
|
||||||
|
true ^ true,
|
||||||
BooleanUtils
|
BooleanUtils
|
||||||
.xor(new Boolean[] { Boolean.FALSE, Boolean.TRUE })
|
.xor(new Boolean[] { Boolean.TRUE, Boolean.TRUE })
|
||||||
.booleanValue());
|
.booleanValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testXor_object_validInput_3items() {
|
public void testXor_object_validInput_3items() {
|
||||||
assertTrue(
|
assertEquals(
|
||||||
"False result for (false, false, true)",
|
"false ^ false ^ false",
|
||||||
|
false ^ false ^ false,
|
||||||
|
BooleanUtils.xor(
|
||||||
|
new Boolean[] {
|
||||||
|
Boolean.FALSE,
|
||||||
|
Boolean.FALSE,
|
||||||
|
Boolean.FALSE })
|
||||||
|
.booleanValue());
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
"false ^ false ^ true",
|
||||||
|
false ^ false ^ true,
|
||||||
BooleanUtils
|
BooleanUtils
|
||||||
.xor(
|
.xor(
|
||||||
new Boolean[] {
|
new Boolean[] {
|
||||||
|
@ -552,8 +579,9 @@ public class BooleanUtilsTest {
|
||||||
Boolean.TRUE })
|
Boolean.TRUE })
|
||||||
.booleanValue());
|
.booleanValue());
|
||||||
|
|
||||||
assertTrue(
|
assertEquals(
|
||||||
"False result for (false, true, false)",
|
"false ^ true ^ false",
|
||||||
|
false ^ true ^ false,
|
||||||
BooleanUtils
|
BooleanUtils
|
||||||
.xor(
|
.xor(
|
||||||
new Boolean[] {
|
new Boolean[] {
|
||||||
|
@ -562,8 +590,9 @@ public class BooleanUtilsTest {
|
||||||
Boolean.FALSE })
|
Boolean.FALSE })
|
||||||
.booleanValue());
|
.booleanValue());
|
||||||
|
|
||||||
assertTrue(
|
assertEquals(
|
||||||
"False result for (true, false, false)",
|
"true ^ false ^ false",
|
||||||
|
true ^ false ^ false,
|
||||||
BooleanUtils
|
BooleanUtils
|
||||||
.xor(
|
.xor(
|
||||||
new Boolean[] {
|
new Boolean[] {
|
||||||
|
@ -572,47 +601,42 @@ public class BooleanUtilsTest {
|
||||||
Boolean.FALSE })
|
Boolean.FALSE })
|
||||||
.booleanValue());
|
.booleanValue());
|
||||||
|
|
||||||
assertTrue(
|
assertEquals(
|
||||||
"True result for (true, true, true)",
|
"true ^ false ^ true",
|
||||||
! BooleanUtils
|
true ^ false ^ true,
|
||||||
|
BooleanUtils.xor(
|
||||||
|
new Boolean[] {
|
||||||
|
Boolean.TRUE,
|
||||||
|
Boolean.FALSE,
|
||||||
|
Boolean.TRUE })
|
||||||
|
.booleanValue());
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
"true ^ true ^ false",
|
||||||
|
true ^ true ^ false,
|
||||||
|
BooleanUtils.xor(
|
||||||
|
new Boolean[] {
|
||||||
|
Boolean.TRUE,
|
||||||
|
Boolean.TRUE,
|
||||||
|
Boolean.FALSE })
|
||||||
|
.booleanValue());
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
"false ^ true ^ true",
|
||||||
|
false ^ true ^ true,
|
||||||
|
BooleanUtils.xor(
|
||||||
|
new Boolean[] {
|
||||||
|
Boolean.FALSE,
|
||||||
|
Boolean.TRUE,
|
||||||
|
Boolean.TRUE })
|
||||||
|
.booleanValue());
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
"true ^ true ^ true",
|
||||||
|
true ^ true ^ true,
|
||||||
|
BooleanUtils
|
||||||
.xor(new Boolean[] { Boolean.TRUE, Boolean.TRUE, Boolean.TRUE })
|
.xor(new Boolean[] { Boolean.TRUE, Boolean.TRUE, Boolean.TRUE })
|
||||||
.booleanValue());
|
.booleanValue());
|
||||||
|
|
||||||
assertTrue(
|
|
||||||
"True result for (false, false)",
|
|
||||||
! BooleanUtils.xor(
|
|
||||||
new Boolean[] {
|
|
||||||
Boolean.FALSE,
|
|
||||||
Boolean.FALSE,
|
|
||||||
Boolean.FALSE })
|
|
||||||
.booleanValue());
|
|
||||||
|
|
||||||
assertTrue(
|
|
||||||
"True result for (true, true, false)",
|
|
||||||
! BooleanUtils.xor(
|
|
||||||
new Boolean[] {
|
|
||||||
Boolean.TRUE,
|
|
||||||
Boolean.TRUE,
|
|
||||||
Boolean.FALSE })
|
|
||||||
.booleanValue());
|
|
||||||
|
|
||||||
assertTrue(
|
|
||||||
"True result for (true, false, true)",
|
|
||||||
! BooleanUtils.xor(
|
|
||||||
new Boolean[] {
|
|
||||||
Boolean.TRUE,
|
|
||||||
Boolean.FALSE,
|
|
||||||
Boolean.TRUE })
|
|
||||||
.booleanValue());
|
|
||||||
|
|
||||||
assertTrue(
|
|
||||||
"False result for (false, true, true)",
|
|
||||||
! BooleanUtils.xor(
|
|
||||||
new Boolean[] {
|
|
||||||
Boolean.FALSE,
|
|
||||||
Boolean.TRUE,
|
|
||||||
Boolean.TRUE })
|
|
||||||
.booleanValue());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// testAnd
|
// testAnd
|
||||||
|
|
Loading…
Reference in New Issue