    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *      http://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 * Unless required by applicable law or agreed to in writing, software
    012 * distributed under the License is distributed on an "AS IS" BASIS,
    013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 * See the License for the specific language governing permissions and
    015 * limitations under the License.
    016 */
    017package org.apache.commons.lang3;
    018
    019import java.util.Arrays;
    020import java.util.Collections;
    021import java.util.List;
    022import java.util.function.Consumer;
    023
    024import org.apache.commons.lang3.math.NumberUtils;
    025
    026/**
    027 * Operations on boolean primitives and Boolean objects.
    028 *
    029 * <p>This class tries to handle {@code null} input gracefully.
    030 * An exception will not be thrown for a {@code null} input.
    031 * Each method documents its behavior in more detail.</p>
    032 *
    033 * <p>#ThreadSafe#</p>
    034 * @since 2.0
    035 */
    036public class BooleanUtils {
    037
    038    private static final List<Boolean> BOOLEAN_LIST = Collections.unmodifiableList(Arrays.asList(Boolean.FALSE, Boolean.TRUE));
    039
    040    /**
    041     * The false String {@code "false"}.
    042     *
    043     * @since 3.12.0
    044     */
    045    public static final String FALSE = "false";
    046
    047    /**
    048     * The no String {@code "no"}.
    049     *
    050     * @since 3.12.0
    051     */
    052    public static final String NO = "no";
    053
    054    /**
    055     * The off String {@code "off"}.
    056     *
    057     * @since 3.12.0
    058     */
    059    public static final String OFF = "off";
    060
    061    /**
    062     * The on String {@code "on"}.
    063     *
    064     * @since 3.12.0
    065     */
    066    public static final String ON = "on";
    067
    068    /**
    069     * The true String {@code "true"}.
    070     *
    071     * @since 3.12.0
    072     */
    073    public static final String TRUE = "true";
    074
    075    /**
    076     * The yes String {@code "yes"}.
    077     *
    078     * @since 3.12.0
    079     */
    080    public static final String YES = "yes";
    081
    082    /**
    083     * Performs an 'and' operation on a set of booleans.
    084     *
    085     * <pre>
    086     *   BooleanUtils.and(true, true)         = true
    087     *   BooleanUtils.and(false, false)       = false
    088     *   BooleanUtils.and(true, false)        = false
    089     *   BooleanUtils.and(true, true, false)  = false
    090     *   BooleanUtils.and(true, true, true)   = true
    091     * </pre>
    092     *
    093     * @param array  an array of {@code boolean}s
    094     * @return the result of the logical 'and' operation. That is {@code false}
    095     * if any of the parameters is {@code false} and {@code true} otherwise.
    096     * @throws NullPointerException if {@code array} is {@code null}
    097     * @throws IllegalArgumentException if {@code array} is empty.
    098     * @since 3.0.1
    099     */
    100    public static boolean and(final boolean... array) {
    101        ObjectUtils.requireNonEmpty(array, "array");
    102        for (final boolean element : array) {
    103            if (!element) {
    104                return false;
    105            }
    106        }
    107        return true;
    108    }
    109
    110    /**
    111     * Performs an 'and' operation on an array of Booleans.
    112     * <pre>
    113     *   BooleanUtils.and(Boolean.TRUE, Boolean.TRUE)                 = Boolean.TRUE
    114     *   BooleanUtils.and(Boolean.FALSE, Boolean.FALSE)               = Boolean.FALSE
    115     *   BooleanUtils.and(Boolean.TRUE, Boolean.FALSE)                = Boolean.FALSE
    116     *   BooleanUtils.and(Boolean.TRUE, Boolean.TRUE, Boolean.TRUE)   = Boolean.TRUE
    117     *   BooleanUtils.and(Boolean.FALSE, Boolean.FALSE, Boolean.TRUE) = Boolean.FALSE
    118     *   BooleanUtils.and(Boolean.TRUE, Boolean.FALSE, Boolean.TRUE)  = Boolean.FALSE
    119     *   BooleanUtils.and(null, null)                                 = Boolean.FALSE
    120     * </pre>
    121     * <p>
    122     * Null array elements map to false, like {@code Boolean.parseBoolean(null)} and its callers return false.
    123     * </p>
    124     *
    125     * @param array  an array of {@link Boolean}s
    126     * @return the result of the logical 'and' operation. That is {@code false}
    127     * if any of the parameters is {@code false} and {@code true} otherwise.
    128     * @throws NullPointerException if {@code array} is {@code null}
    129     * @throws IllegalArgumentException if {@code array} is empty.
    130     * @since 3.0.1
    131     */
    132    public static Boolean and(final Boolean... array) {
    133        ObjectUtils.requireNonEmpty(array, "array");
    134        return and(ArrayUtils.toPrimitive(array)) ? Boolean.TRUE : Boolean.FALSE;
    135    }
    136
    137    /**
    138     * Returns a new array of possible values (like an enum would).
    139     * @return a new array of possible values (like an enum would).
    140     * @since 3.12.0
    141     */
    142    public static Boolean[] booleanValues() {
    143        return new Boolean[] {Boolean.FALSE, Boolean.TRUE};
    144    }
    145
    146    /**
    147     * Compares two {@code boolean} values. This is the same functionality as provided in Java 7.
    148     *
    149     * @param x the first {@code boolean} to compare
    150     * @param y the second {@code boolean} to compare
    151     * @return the value {@code 0} if {@code x == y};
    152     *         a value less than {@code 0} if {@code !x && y}; and
    153     *         a value greater than {@code 0} if {@code x && !y}
    154     * @since 3.4
    155     */
    156    public static int compare(final boolean x, final boolean y) {
    157        if (x == y) {
    158            return 0;
    159        }
    160        return x ? 1 : -1;
    161    }
    162
    163    /**
    164     * Performs the given action for each Boolean {@link BooleanUtils#values()}.
    165     *
    166     * @param action The action to be performed for each element
    167     * @since 3.13.0
    168     */
    169    public static void forEach(final Consumer<Boolean> action) {
    170        values().forEach(action);
    171    }
    172
    173    /**
    174     * Checks if a {@link Boolean} value is {@code false},
    175     * handling {@code null} by returning {@code false}.
    176     *
    177     * <pre>
    178     *   BooleanUtils.isFalse(Boolean.TRUE)  = false
    179     *   BooleanUtils.isFalse(Boolean.FALSE) = true
    180     *   BooleanUtils.isFalse(null)          = false
    181     * </pre>
    182     *
    183     * @param bool  the boolean to check, null returns {@code false}
    184     * @return {@code true} only if the input is non-{@code null} and {@code false}
    185     * @since 2.1
    186     */
    187    public static boolean isFalse(final Boolean bool) {
    188        return Boolean.FALSE.equals(bool);
    189    }
    190
    191    /**
    192     * Checks if a {@link Boolean} value is <i>not</i> {@code false},
    193     * handling {@code null} by returning {@code true}.
    194     *
    195     * <pre>
    196     *   BooleanUtils.isNotFalse(Boolean.TRUE)  = true
    197     *   BooleanUtils.isNotFalse(Boolean.FALSE) = false
    198     *   BooleanUtils.isNotFalse(null)          = true
    199     * </pre>
    200     *
    201     * @param bool  the boolean to check, null returns {@code true}
    202     * @return {@code true} if the input is {@code null} or {@code true}
    203     * @since 2.3
    204     */
    205    public static boolean isNotFalse(final Boolean bool) {
    206        return !isFalse(bool);
    207    }
    208
    209    /**
    210     * Checks if a {@link Boolean} value is <i>not</i> {@code true},
    211     * handling {@code null} by returning {@code true}.
    212     *
    213     * <pre>
    214     *   BooleanUtils.isNotTrue(Boolean.TRUE)  = false
    215     *   BooleanUtils.isNotTrue(Boolean.FALSE) = true
    216     *   BooleanUtils.isNotTrue(null)          = true
    217     * </pre>
    218     *
    219     * @param bool  the boolean to check, null returns {@code true}
    220     * @return {@code true} if the input is null or false
    221     * @since 2.3
    222     */
    223    public static boolean isNotTrue(final Boolean bool) {
    224        return !isTrue(bool);
    225    }
    226
    227    /**
    228     * Checks if a {@link Boolean} value is {@code true},
    229     * handling {@code null} by returning {@code false}.
    230     *
    231     * <pre>
    232     *   BooleanUtils.isTrue(Boolean.TRUE)  = true
    233     *   BooleanUtils.isTrue(Boolean.FALSE) = false
    234     *   BooleanUtils.isTrue(null)          = false
    235     * </pre>
    236     *
    237     * @param bool the boolean to check, {@code null} returns {@code false}
    238     * @return {@code true} only if the input is non-null and true
    239     * @since 2.1
    240     */
    241    public static boolean isTrue(final Boolean bool) {
    242        return Boolean.TRUE.equals(bool);
    243    }
    244    /**
    245     * Negates the specified boolean.
    246     *
    247     * <p>If {@code null} is passed in, {@code null} will be returned.</p>
    248     *
    249     * <p>NOTE: This returns {@code null} and will throw a {@link NullPointerException}
    250     * if unboxed to a boolean.</p>
    251     *
    252     * <pre>
    253     *   BooleanUtils.negate(Boolean.TRUE)  = Boolean.FALSE;
    254     *   BooleanUtils.negate(Boolean.FALSE) = Boolean.TRUE;
    255     *   BooleanUtils.negate(null)          = null;
    256     * </pre>
    257     *
    258     * @param bool  the Boolean to negate, may be null
    259     * @return the negated Boolean, or {@code null} if {@code null} input
    260     */
    261    public static Boolean negate(final Boolean bool) {
    262        if (bool == null) {
    263            return null;
    264        }
    265        return bool.booleanValue() ? Boolean.FALSE : Boolean.TRUE;
    266    }
    267
    268    /**
    269     * Performs a one-hot on an array of booleans.
    270     * <p>
    271     * This implementation returns true if one, and only one, of the supplied values is true.
    272     * </p>
    273     * <p>
    274     * See also <a href="https://en.wikipedia.org/wiki/One-hot">One-hot</a>.
    275     * </p>
    276     * @param array  an array of {@code boolean}s
    277     * @return the result of the one-hot operations
    278     * @throws NullPointerException if {@code array} is {@code null}
    279     * @throws IllegalArgumentException if {@code array} is empty.
    280     */
    281    public static boolean oneHot(final boolean... array) {
    282        ObjectUtils.requireNonEmpty(array, "array");
    283        boolean result = false;
    284        for (final boolean element: array) {
    285            if (element) {
    286                if (result) {
    287                    return false;
    288                }
    289                result = true;
    290            }
    291        }
    292        return result;
    293    }
    294
    295    /**
    296     * Performs a one-hot on an array of booleans.
    297     * <p>
    298     * This implementation returns true if one, and only one, of the supplied values is true.
    299     * </p>
    300     * <p>
    301     * Null array elements map to false, like {@code Boolean.parseBoolean(null)} and its callers return false.
    302     * </p>
    303     * <p>
    304     * See also <a href="https://en.wikipedia.org/wiki/One-hot">One-hot</a>.
    305     * </p>
    306     *
    307     * @param array  an array of {@code boolean}s
    308     * @return the result of the one-hot operations
    309     * @throws NullPointerException if {@code array} is {@code null}
    310     * @throws IllegalArgumentException if {@code array} is empty.
    311     */
    312    public static Boolean oneHot(final Boolean... array) {
    313        return Boolean.valueOf(oneHot(ArrayUtils.toPrimitive(array)));
    314    }
    315
    316    /**
    317     * Performs an 'or' operation on a set of booleans.
    318     *
    319     * <pre>
    320     *   BooleanUtils.or(true, true)          = true
    321     *   BooleanUtils.or(false, false)        = false
    322     *   BooleanUtils.or(true, false)         = true
    323     *   BooleanUtils.or(true, true, false)   = true
    324     *   BooleanUtils.or(true, true, true)    = true
    325     *   BooleanUtils.or(false, false, false) = false
    326     * </pre>
    327     *
    328     * @param array  an array of {@code boolean}s
    329     * @return {@code true} if any of the arguments is {@code true}, and it returns {@code false} otherwise.
    330     * @throws NullPointerException if {@code array} is {@code null}
    331     * @throws IllegalArgumentException if {@code array} is empty.
    332     * @since 3.0.1
    333     */
    334    public static boolean or(final boolean... array) {
    335        ObjectUtils.requireNonEmpty(array, "array");
    336        for (final boolean element : array) {
    337            if (element) {
    338                return true;
    339            }
    340        }
    341        return false;
    342    }
    343
    344    /**
    345     * Performs an 'or' operation on an array of Booleans.
    346     * <pre>
    347     *   BooleanUtils.or(Boolean.TRUE, Boolean.TRUE)                  = Boolean.TRUE
    348     *   BooleanUtils.or(Boolean.FALSE, Boolean.FALSE)                = Boolean.FALSE
    349     *   BooleanUtils.or(Boolean.TRUE, Boolean.FALSE)                 = Boolean.TRUE
    350     *   BooleanUtils.or(Boolean.TRUE, Boolean.TRUE, Boolean.TRUE)    = Boolean.TRUE
    351     *   BooleanUtils.or(Boolean.FALSE, Boolean.FALSE, Boolean.TRUE)  = Boolean.TRUE
    352     *   BooleanUtils.or(Boolean.TRUE, Boolean.FALSE, Boolean.TRUE)   = Boolean.TRUE
    353     *   BooleanUtils.or(Boolean.FALSE, Boolean.FALSE, Boolean.FALSE) = Boolean.FALSE
    354     *   BooleanUtils.or(Boolean.TRUE, null)                          = Boolean.TRUE
    355     *   BooleanUtils.or(Boolean.FALSE, null)                         = Boolean.FALSE
    356     * </pre>
    357     * <p>
    358     * Null array elements map to false, like {@code Boolean.parseBoolean(null)} and its callers return false.
    359     * </p>
    360     *
    361     * @param array  an array of {@link Boolean}s
    362     * @return {@code true} if any of the arguments is {@code true}, and it returns {@code false} otherwise.
    363     * @throws NullPointerException if {@code array} is {@code null}
    364     * @throws IllegalArgumentException if {@code array} is empty.
    365     * @since 3.0.1
    366     */
    367    public static Boolean or(final Boolean... array) {
    368        ObjectUtils.requireNonEmpty(array, "array");
    369        return or(ArrayUtils.toPrimitive(array)) ? Boolean.TRUE : Boolean.FALSE;
    370    }
    371
    372    /**
    373     * Returns a new array of possible values (like an enum would).
    374     * @return a new array of possible values (like an enum would).
    375     * @since 3.12.0
    376     */
    377    public static boolean[] primitiveValues() {
    378        return new boolean[] {false, true};
    379    }
    380
    381    /**
    382     * Converts a Boolean to a boolean handling {@code null}
    383     * by returning {@code false}.
    384     *
    385     * <pre>
    386     *   BooleanUtils.toBoolean(Boolean.TRUE)  = true
    387     *   BooleanUtils.toBoolean(Boolean.FALSE) = false
    388     *   BooleanUtils.toBoolean(null)          = false
    389     * </pre>
    390     *
    391     * @param bool  the boolean to convert
    392     * @return {@code true} or {@code false}, {@code null} returns {@code false}
    393     */
    394    public static boolean toBoolean(final Boolean bool) {
    395        return bool != null && bool.booleanValue();
    396    }
    397
    398    /**
    399     * Converts an int to a boolean using the convention that {@code zero}
    400     * is {@code false}, everything else is {@code true}.
    401     *
    402     * <pre>
    403     *   BooleanUtils.toBoolean(0) = false
    404     *   BooleanUtils.toBoolean(1) = true
    405     *   BooleanUtils.toBoolean(2) = true
    406     * </pre>
    407     *
    408     * @param value  the int to convert
    409     * @return {@code true} if non-zero, {@code false}
    410     *  if zero
    411     */
    412    public static boolean toBoolean(final int value) {
    413        return value != 0;
    414    }
    415
    416    /**
    417     * Converts an int to a boolean specifying the conversion values.
    418     *
    419     * <p>If the {@code trueValue} and {@code falseValue} are the same number then
    420     * the return value will be {@code true} in case {@code value} matches it.</p>
    421     *
    422     * <pre>
    423     *   BooleanUtils.toBoolean(0, 1, 0) = false
    424     *   BooleanUtils.toBoolean(1, 1, 0) = true
    425     *   BooleanUtils.toBoolean(1, 1, 1) = true
    426     *   BooleanUtils.toBoolean(2, 1, 2) = false
    427     *   BooleanUtils.toBoolean(2, 2, 0) = true
    428     * </pre>
    429     *
    430     * @param value  the {@link Integer} to convert
    431     * @param trueValue  the value to match for {@code true}
    432     * @param falseValue  the value to match for {@code false}
    433     * @return {@code true} or {@code false}
    434     * @throws IllegalArgumentException if {@code value} does not match neither
    435     * {@code trueValue} no {@code falseValue}
    436     */
    437    public static boolean toBoolean(final int value, final int trueValue, final int falseValue) {
    438        if (value == trueValue) {
    439            return true;
    440        }
    441        if (value == falseValue) {
    442            return false;
    443        }
    444        throw new IllegalArgumentException("The Integer did not match either specified value");
    445    }
    446
    447    /**
    448     * Converts an Integer to a boolean specifying the conversion values.
    449     *
    450     * <pre>
    451     *   BooleanUtils.toBoolean(Integer.valueOf(0), Integer.valueOf(1), Integer.valueOf(0)) = false
    452     *   BooleanUtils.toBoolean(Integer.valueOf(1), Integer.valueOf(1), Integer.valueOf(0)) = true
    453     *   BooleanUtils.toBoolean(Integer.valueOf(2), Integer.valueOf(1), Integer.valueOf(2)) = false
    454     *   BooleanUtils.toBoolean(Integer.valueOf(2), Integer.valueOf(2), Integer.valueOf(0)) = true
    455     *   BooleanUtils.toBoolean(null, null, Integer.valueOf(0))                     = true
    456     * </pre>
    457     *
    458     * @param value  the Integer to convert
    459     * @param trueValue  the value to match for {@code true}, may be {@code null}
    460     * @param falseValue  the value to match for {@code false}, may be {@code null}
    461     * @return {@code true} or {@code false}
    462     * @throws IllegalArgumentException if no match
    463     */
    464    public static boolean toBoolean(final Integer value, final Integer trueValue, final Integer falseValue) {
    465        if (value == null) {
    466            if (trueValue == null) {
    467                return true;
    468            }
    469            if (falseValue == null) {
    470                return false;
    471            }
    472        } else if (value.equals(trueValue)) {
    473            return true;
    474        } else if (value.equals(falseValue)) {
    475            return false;
    476        }
    477        throw new IllegalArgumentException("The Integer did not match either specified value");
    478    }
    479
    480    /**
    481     * Converts a String to a boolean (optimised for performance).
    482     *
    483     * <p>{@code 'true'}, {@code 'on'}, {@code 'y'}, {@code 't'} or {@code 'yes'}
    484     * (case insensitive) will return {@code true}. Otherwise,
    485     * {@code false} is returned.</p>
    486     *
    487     * <p>This method performs 4 times faster (JDK1.4) than
    488     * {@code Boolean.valueOf(String)}. However, this method accepts
    489     * 'on' and 'yes', 't', 'y' as true values.
    490     *
    491     * <pre>
    492     *   BooleanUtils.toBoolean(null)    = false
    493     *   BooleanUtils.toBoolean("true")  = true
    494     *   BooleanUtils.toBoolean("TRUE")  = true
    495     *   BooleanUtils.toBoolean("tRUe")  = true
    496     *   BooleanUtils.toBoolean("on")    = true
    497     *   BooleanUtils.toBoolean("yes")   = true
    498     *   BooleanUtils.toBoolean("false") = false
    499     *   BooleanUtils.toBoolean("x gti") = false
    500     *   BooleanUtils.toBoolean("y") = true
    501     *   BooleanUtils.toBoolean("n") = false
    502     *   BooleanUtils.toBoolean("t") = true
    503     *   BooleanUtils.toBoolean("f") = false
    504     * </pre>
    505     *
    506     * @param str  the String to check
    507     * @return the boolean value of the string, {@code false} if no match or the String is null
    508     */
    509    public static boolean toBoolean(final String str) {
    510        return toBooleanObject(str) == Boolean.TRUE;
    511    }
    512
    513    /**
    514     * Converts a String to a Boolean throwing an exception if no match found.
    515     *
    516     * <pre>
    517     *   BooleanUtils.toBoolean("true", "true", "false")  = true
    518     *   BooleanUtils.toBoolean("false", "true", "false") = false
    519     * </pre>
    520     *
    521     * @param str  the String to check
    522     * @param trueString  the String to match for {@code true} (case-sensitive), may be {@code null}
    523     * @param falseString  the String to match for {@code false} (case-sensitive), may be {@code null}
    524     * @return the boolean value of the string
    525     * @throws IllegalArgumentException if the String doesn't match
    526     */
    527    public static boolean toBoolean(final String str, final String trueString, final String falseString) {
    528        if (str == trueString) {
    529            return true;
    530        }
    531        if (str == falseString) {
    532            return false;
    533        }
    534        if (str != null) {
    535            if (str.equals(trueString)) {
    536                return true;
    537            }
    538            if (str.equals(falseString)) {
    539                return false;
    540            }
    541        }
    542        throw new IllegalArgumentException("The String did not match either specified value");
    543    }
    544
    545    /**
    546     * Converts a Boolean to a boolean handling {@code null}.
    547     *
    548     * <pre>
    549     *   BooleanUtils.toBooleanDefaultIfNull(Boolean.TRUE, false)  = true
    550     *   BooleanUtils.toBooleanDefaultIfNull(Boolean.TRUE, true)   = true
    551     *   BooleanUtils.toBooleanDefaultIfNull(Boolean.FALSE, true)  = false
    552     *   BooleanUtils.toBooleanDefaultIfNull(Boolean.FALSE, false) = false
    553     *   BooleanUtils.toBooleanDefaultIfNull(null, true)           = true
    554     *   BooleanUtils.toBooleanDefaultIfNull(null, false)          = false
    555     * </pre>
    556     *
    557     * @param bool  the boolean object to convert to primitive
    558     * @param valueIfNull  the boolean value to return if the parameter {@code bool} is {@code null}
    559     * @return {@code true} or {@code false}
    560     */
    561    public static boolean toBooleanDefaultIfNull(final Boolean bool, final boolean valueIfNull) {
    562        if (bool == null) {
    563            return valueIfNull;
    564        }
    565        return bool.booleanValue();
    566    }
    567
    568    /**
    569     * Converts an int to a Boolean using the convention that {@code zero}
    570     * is {@code false}, everything else is {@code true}.
    571     *
    572     * <pre>
    573     *   BooleanUtils.toBoolean(0) = Boolean.FALSE
    574     *   BooleanUtils.toBoolean(1) = Boolean.TRUE
    575     *   BooleanUtils.toBoolean(2) = Boolean.TRUE
    576     * </pre>
    577     *
    578     * @param value  the int to convert
    579     * @return Boolean.TRUE if non-zero, Boolean.FALSE if zero,
    580     *  {@code null} if {@code null}
    581     */
    582    public static Boolean toBooleanObject(final int value) {
    583        return value == 0 ? Boolean.FALSE : Boolean.TRUE;
    584    }
    585
    586    /**
    587     * Converts an int to a Boolean specifying the conversion values.
    588     *
    589     * <p>NOTE: This method may return {@code null} and may throw a {@link NullPointerException}
    590     * if unboxed to a {@code boolean}.</p>
    591     *
    592     * <p>The checks are done first for the {@code trueValue}, then for the {@code falseValue} and
    593     * finally for the {@code nullValue}.</p>
    594     *
    595     * <pre>
    596     *   BooleanUtils.toBooleanObject(0, 0, 2, 3) = Boolean.TRUE
    597     *   BooleanUtils.toBooleanObject(0, 0, 0, 3) = Boolean.TRUE
    598     *   BooleanUtils.toBooleanObject(0, 0, 0, 0) = Boolean.TRUE
    599     *   BooleanUtils.toBooleanObject(2, 1, 2, 3) = Boolean.FALSE
    600     *   BooleanUtils.toBooleanObject(2, 1, 2, 2) = Boolean.FALSE
    601     *   BooleanUtils.toBooleanObject(3, 1, 2, 3) = null
    602     * </pre>
    603     *
    604     * @param value  the Integer to convert
    605     * @param trueValue  the value to match for {@code true}
    606     * @param falseValue  the value to match for {@code false}
    607     * @param nullValue  the value to match for {@code null}
    608     * @return Boolean.TRUE, Boolean.FALSE, or {@code null}
    609     * @throws IllegalArgumentException if no match
    610     */
    611    public static Boolean toBooleanObject(final int value, final int trueValue, final int falseValue, final int nullValue) {
    612        if (value == trueValue) {
    613            return Boolean.TRUE;
    614        }
    615        if (value == falseValue) {
    616            return Boolean.FALSE;
    617        }
    618        if (value == nullValue) {
    619            return null;
    620        }
    621        throw new IllegalArgumentException("The Integer did not match any specified value");
    622    }
    623
    624    /**
    625     * Converts an Integer to a Boolean using the convention that {@code zero}
    626     * is {@code false}, every other numeric value is {@code true}.
    627     *
    628     * <p>{@code null} will be converted to {@code null}.</p>
    629     *
    630     * <p>NOTE: This method may return {@code null} and may throw a {@link NullPointerException}
    631     * if unboxed to a {@code boolean}.</p>
    632     *
    633     * <pre>
    634     *   BooleanUtils.toBooleanObject(Integer.valueOf(0))    = Boolean.FALSE
    635     *   BooleanUtils.toBooleanObject(Integer.valueOf(1))    = Boolean.TRUE
    636     *   BooleanUtils.toBooleanObject(Integer.valueOf(null)) = null
    637     * </pre>
    638     *
    639     * @param value  the Integer to convert
    640     * @return Boolean.TRUE if non-zero, Boolean.FALSE if zero,
    641     *  {@code null} if {@code null} input
    642     */
    643    public static Boolean toBooleanObject(final Integer value) {
    644        if (value == null) {
    645            return null;
    646        }
    647        return value.intValue() == 0 ? Boolean.FALSE : Boolean.TRUE;
    648    }
    649
    650    /**
    651     * Converts an Integer to a Boolean specifying the conversion values.
    652     *
    653     * <p>NOTE: This method may return {@code null} and may throw a {@link NullPointerException}
    654     * if unboxed to a {@code boolean}.</p>
    655     *
    656     * <p>The checks are done first for the {@code trueValue}, then for the {@code falseValue} and
    657     * finally for the {@code nullValue}.</p>
    658     **
    659     * <pre>
    660     *   BooleanUtils.toBooleanObject(Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(2), Integer.valueOf(3)) = Boolean.TRUE
    661     *   BooleanUtils.toBooleanObject(Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(3)) = Boolean.TRUE
    662     *   BooleanUtils.toBooleanObject(Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(0)) = Boolean.TRUE
    663     *   BooleanUtils.toBooleanObject(Integer.valueOf(2), Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3)) = Boolean.FALSE
    664     *   BooleanUtils.toBooleanObject(Integer.valueOf(2), Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(2)) = Boolean.FALSE
    665     *   BooleanUtils.toBooleanObject(Integer.valueOf(3), Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3)) = null
    666     * </pre>
    667     *
    668     * @param value  the Integer to convert
    669     * @param trueValue  the value to match for {@code true}, may be {@code null}
    670     * @param falseValue  the value to match for {@code false}, may be {@code null}
    671     * @param nullValue  the value to match for {@code null}, may be {@code null}
    672     * @return Boolean.TRUE, Boolean.FALSE, or {@code null}
    673     * @throws IllegalArgumentException if no match
    674     */
    675    public static Boolean toBooleanObject(final Integer value, final Integer trueValue, final Integer falseValue, final Integer nullValue) {
    676        if (value == null) {
    677            if (trueValue == null) {
    678                return Boolean.TRUE;
    679            }
    680            if (falseValue == null) {
    681                return Boolean.FALSE;
    682            }
    683            if (nullValue == null) {
    684                return null;
    685            }
    686        } else if (value.equals(trueValue)) {
    687            return Boolean.TRUE;
    688        } else if (value.equals(falseValue)) {
    689            return Boolean.FALSE;
    690        } else if (value.equals(nullValue)) {
    691            return null;
    692        }
    693        throw new IllegalArgumentException("The Integer did not match any specified value");
    694    }
    695
    696    /**
    697     * Converts a String to a Boolean.
    698     *
    699     * <p>{@code 'true'}, {@code 'on'}, {@code 'y'}, {@code 't'}, {@code 'yes'}
    700     * or {@code '1'} (case insensitive) will return {@code true}.
    701     * {@code 'false'}, {@code 'off'}, {@code 'n'}, {@code 'f'}, {@code 'no'}
    702     * or {@code '0'} (case insensitive) will return {@code false}.
    703     * Otherwise, {@code null} is returned.</p>
    704     *
    705     * <p>NOTE: This method may return {@code null} and may throw a {@link NullPointerException}
    706     * if unboxed to a {@code boolean}.</p>
    707     *
    708     * <pre>
    709     *   // N.B. case is not significant
    710     *   BooleanUtils.toBooleanObject(null)    = null
    711     *   BooleanUtils.toBooleanObject("true")  = Boolean.TRUE
    712     *   BooleanUtils.toBooleanObject("T")     = Boolean.TRUE // i.e. T[RUE]
    713     *   BooleanUtils.toBooleanObject("false") = Boolean.FALSE
    714     *   BooleanUtils.toBooleanObject("f")     = Boolean.FALSE // i.e. f[alse]
    715     *   BooleanUtils.toBooleanObject("No")    = Boolean.FALSE
    716     *   BooleanUtils.toBooleanObject("n")     = Boolean.FALSE // i.e. n[o]
    717     *   BooleanUtils.toBooleanObject("on")    = Boolean.TRUE
    718     *   BooleanUtils.toBooleanObject("ON")    = Boolean.TRUE
    719     *   BooleanUtils.toBooleanObject("off")   = Boolean.FALSE
    720     *   BooleanUtils.toBooleanObject("oFf")   = Boolean.FALSE
    721     *   BooleanUtils.toBooleanObject("yes")   = Boolean.TRUE
    722     *   BooleanUtils.toBooleanObject("Y")     = Boolean.TRUE // i.e. Y[ES]
    723     *   BooleanUtils.toBooleanObject("1")     = Boolean.TRUE
    724     *   BooleanUtils.toBooleanObject("0")     = Boolean.FALSE
    725     *   BooleanUtils.toBooleanObject("blue")  = null
    726     *   BooleanUtils.toBooleanObject("true ") = null // trailing space (too long)
    727     *   BooleanUtils.toBooleanObject("ono")   = null // does not match on or no
    728     * </pre>
    729     *
    730     * @param str  the String to check; upper and lower case are treated as the same
    731     * @return the Boolean value of the string, {@code null} if no match or {@code null} input
    732     */
    733    public static Boolean toBooleanObject(final String str) {
    734        // Previously used equalsIgnoreCase, which was fast for interned 'true'.
    735        // Non interned 'true' matched 15 times slower.
    736        //
    737        // Optimisation provides same performance as before for interned 'true'.
    738        // Similar performance for null, 'false', and other strings not length 2/3/4.
    739        // 'true'/'TRUE' match 4 times slower, 'tRUE'/'True' 7 times slower.
    740        if (str == TRUE) {
    741            return Boolean.TRUE;
    742        }
    743        if (str == null) {
    744            return null;
    745        }
    746        switch (str.length()) {
    747            case 1: {
    748                final char ch0 = str.charAt(0);
    749                if (ch0 == 'y' || ch0 == 'Y' ||
    750                    ch0 == 't' || ch0 == 'T' ||
    751                    ch0 == '1') {
    752                    return Boolean.TRUE;
    753                }
    754                if (ch0 == 'n' || ch0 == 'N' ||
    755                    ch0 == 'f' || ch0 == 'F' ||
    756                    ch0 == '0') {
    757                    return Boolean.FALSE;
    758                }
    759                break;
    760            }
    761            case 2: {
    762                final char ch0 = str.charAt(0);
    763                final char ch1 = str.charAt(1);
    764                if ((ch0 == 'o' || ch0 == 'O') &&
    765                    (ch1 == 'n' || ch1 == 'N') ) {
    766                    return Boolean.TRUE;
    767                }
    768                if ((ch0 == 'n' || ch0 == 'N') &&
    769                    (ch1 == 'o' || ch1 == 'O') ) {
    770                    return Boolean.FALSE;
    771                }
    772                break;
    773            }
    774            case 3: {
    775                final char ch0 = str.charAt(0);
    776                final char ch1 = str.charAt(1);
    777                final char ch2 = str.charAt(2);
    778                if ((ch0 == 'y' || ch0 == 'Y') &&
    779                    (ch1 == 'e' || ch1 == 'E') &&
    780                    (ch2 == 's' || ch2 == 'S') ) {
    781                    return Boolean.TRUE;
    782                }
    783                if ((ch0 == 'o' || ch0 == 'O') &&
    784                    (ch1 == 'f' || ch1 == 'F') &&
    785                    (ch2 == 'f' || ch2 == 'F') ) {
    786                    return Boolean.FALSE;
    787                }
    788                break;
    789            }
    790            case 4: {
    791                final char ch0 = str.charAt(0);
    792                final char ch1 = str.charAt(1);
    793                final char ch2 = str.charAt(2);
    794                final char ch3 = str.charAt(3);
    795                if ((ch0 == 't' || ch0 == 'T') &&
    796                    (ch1 == 'r' || ch1 == 'R') &&
    797                    (ch2 == 'u' || ch2 == 'U') &&
    798                    (ch3 == 'e' || ch3 == 'E') ) {
    799                    return Boolean.TRUE;
    800                }
    801                break;
    802            }
    803            case 5: {
    804                final char ch0 = str.charAt(0);
    805                final char ch1 = str.charAt(1);
    806                final char ch2 = str.charAt(2);
    807                final char ch3 = str.charAt(3);
    808                final char ch4 = str.charAt(4);
    809                if ((ch0 == 'f' || ch0 == 'F') &&
    810                    (ch1 == 'a' || ch1 == 'A') &&
    811                    (ch2 == 'l' || ch2 == 'L') &&
    812                    (ch3 == 's' || ch3 == 'S') &&
    813                    (ch4 == 'e' || ch4 == 'E') ) {
    814                    return Boolean.FALSE;
    815                }
    816                break;
    817            }
    818        default:
    819            break;
    820        }
    821
    822        return null;
    823    }
    824
    825    /**
    826     * Converts a String to a Boolean throwing an exception if no match.
    827     *
    828     * <p>NOTE: This method may return {@code null} and may throw a {@link NullPointerException}
    829     * if unboxed to a {@code boolean}.</p>
    830     *
    831     * <pre>
    832     *   BooleanUtils.toBooleanObject("true", "true", "false", "null")   = Boolean.TRUE
    833     *   BooleanUtils.toBooleanObject(null, null, "false", "null")       = Boolean.TRUE
    834     *   BooleanUtils.toBooleanObject(null, null, null, "null")          = Boolean.TRUE
    835     *   BooleanUtils.toBooleanObject(null, null, null, null)            = Boolean.TRUE
    836     *   BooleanUtils.toBooleanObject("false", "true", "false", "null")  = Boolean.FALSE
    837     *   BooleanUtils.toBooleanObject("false", "true", "false", "false") = Boolean.FALSE
    838     *   BooleanUtils.toBooleanObject(null, "true", null, "false")       = Boolean.FALSE
    839     *   BooleanUtils.toBooleanObject(null, "true", null, null)          = Boolean.FALSE
    840     *   BooleanUtils.toBooleanObject("null", "true", "false", "null")   = null
    841     * </pre>
    842     *
    843     * @param str  the String to check
    844     * @param trueString  the String to match for {@code true} (case-sensitive), may be {@code null}
    845     * @param falseString  the String to match for {@code false} (case-sensitive), may be {@code null}
    846     * @param nullString  the String to match for {@code null} (case-sensitive), may be {@code null}
    847     * @return the Boolean value of the string, {@code null} if either the String matches {@code nullString}
    848     *  or if {@code null} input and {@code nullString} is {@code null}
    849     * @throws IllegalArgumentException if the String doesn't match
    850     */
    851    public static Boolean toBooleanObject(final String str, final String trueString, final String falseString, final String nullString) {
    852        if (str == null) {
    853            if (trueString == null) {
    854                return Boolean.TRUE;
    855            }
    856            if (falseString == null) {
    857                return Boolean.FALSE;
    858            }
    859            if (nullString == null) {
    860                return null;
    861            }
    862        } else if (str.equals(trueString)) {
    863            return Boolean.TRUE;
    864        } else if (str.equals(falseString)) {
    865            return Boolean.FALSE;
    866        } else if (str.equals(nullString)) {
    867            return null;
    868        }
    869        // no match
    870        throw new IllegalArgumentException("The String did not match any specified value");
    871    }
    872
    873    /**
    874     * Converts a boolean to an int using the convention that
    875     * {@code true} is {@code 1} and {@code false} is {@code 0}.
    876     *
    877     * <pre>
    878     *   BooleanUtils.toInteger(true)  = 1
    879     *   BooleanUtils.toInteger(false) = 0
    880     * </pre>
    881     *
    882     * @param bool  the boolean to convert
    883     * @return one if {@code true}, zero if {@code false}
    884     */
    885    public static int toInteger(final boolean bool) {
    886        return bool ? 1 : 0;
    887    }
    888
    889    /**
    890     * Converts a boolean to an int specifying the conversion values.
    891     *
    892     * <pre>
    893     *   BooleanUtils.toInteger(true, 1, 0)  = 1
    894     *   BooleanUtils.toInteger(false, 1, 0) = 0
    895     * </pre>
    896     *
    897     * @param bool  the to convert
    898     * @param trueValue  the value to return if {@code true}
    899     * @param falseValue  the value to return if {@code false}
    900     * @return the appropriate value
    901     */
    902    public static int toInteger(final boolean bool, final int trueValue, final int falseValue) {
    903        return bool ? trueValue : falseValue;
    904    }
    905
    906    /**
    907     * Converts a Boolean to an int specifying the conversion values.
    908     *
    909     * <pre>
    910     *   BooleanUtils.toInteger(Boolean.TRUE, 1, 0, 2)  = 1
    911     *   BooleanUtils.toInteger(Boolean.FALSE, 1, 0, 2) = 0
    912     *   BooleanUtils.toInteger(null, 1, 0, 2)          = 2
    913     * </pre>
    914     *
    915     * @param bool  the Boolean to convert
    916     * @param trueValue  the value to return if {@code true}
    917     * @param falseValue  the value to return if {@code false}
    918     * @param nullValue  the value to return if {@code null}
    919     * @return the appropriate value
    920     */
    921    public static int toInteger(final Boolean bool, final int trueValue, final int falseValue, final int nullValue) {
    922        if (bool == null) {
    923            return nullValue;
    924        }
    925        return bool.booleanValue() ? trueValue : falseValue;
    926    }
    927
    928    /**
    929     * Converts a boolean to an Integer using the convention that
    930     * {@code true} is {@code 1} and {@code false} is {@code 0}.
    931     *
    932     * <pre>
    933     *   BooleanUtils.toIntegerObject(true)  = Integer.valueOf(1)
    934     *   BooleanUtils.toIntegerObject(false) = Integer.valueOf(0)
    935     * </pre>
    936     *
    937     * @param bool  the boolean to convert
    938     * @return one if {@code true}, zero if {@code false}
    939     */
    940    public static Integer toIntegerObject(final boolean bool) {
    941        return bool ? NumberUtils.INTEGER_ONE : NumberUtils.INTEGER_ZERO;
    942    }
    943
    944    /**
    945     * Converts a boolean to an Integer specifying the conversion values.
    946     *
    947     * <pre>
    948     *   BooleanUtils.toIntegerObject(true, Integer.valueOf(1), Integer.valueOf(0))  = Integer.valueOf(1)
    949     *   BooleanUtils.toIntegerObject(false, Integer.valueOf(1), Integer.valueOf(0)) = Integer.valueOf(0)
    950     * </pre>
    951     *
    952     * @param bool  the to convert
    953     * @param trueValue  the value to return if {@code true}, may be {@code null}
    954     * @param falseValue  the value to return if {@code false}, may be {@code null}
    955     * @return the appropriate value
    956     */
    957    public static Integer toIntegerObject(final boolean bool, final Integer trueValue, final Integer falseValue) {
    958        return bool ? trueValue : falseValue;
    959    }
    960
    961    /**
    962     * Converts a Boolean to a Integer using the convention that
    963     * {@code zero} is {@code false}.
    964     *
    965     * <p>{@code null} will be converted to {@code null}.</p>
    966     *
    967     * <pre>
    968     *   BooleanUtils.toIntegerObject(Boolean.TRUE)  = Integer.valueOf(1)
    969     *   BooleanUtils.toIntegerObject(Boolean.FALSE) = Integer.valueOf(0)
    970     * </pre>
    971     *
    972     * @param bool  the Boolean to convert
    973     * @return one if Boolean.TRUE, zero if Boolean.FALSE, {@code null} if {@code null}
    974     */
    975    public static Integer toIntegerObject(final Boolean bool) {
    976        if (bool == null) {
    977            return null;
    978        }
    979        return bool.booleanValue() ? NumberUtils.INTEGER_ONE : NumberUtils.INTEGER_ZERO;
    980    }
    981
    982    /**
    983     * Converts a Boolean to an Integer specifying the conversion values.
    984     *
    985     * <pre>
    986     *   BooleanUtils.toIntegerObject(Boolean.TRUE, Integer.valueOf(1), Integer.valueOf(0), Integer.valueOf(2))  = Integer.valueOf(1)
    987     *   BooleanUtils.toIntegerObject(Boolean.FALSE, Integer.valueOf(1), Integer.valueOf(0), Integer.valueOf(2)) = Integer.valueOf(0)
    988     *   BooleanUtils.toIntegerObject(null, Integer.valueOf(1), Integer.valueOf(0), Integer.valueOf(2))          = Integer.valueOf(2)
    989     * </pre>
    990     *
    991     * @param bool  the Boolean to convert
    992     * @param trueValue  the value to return if {@code true}, may be {@code null}
    993     * @param falseValue  the value to return if {@code false}, may be {@code null}
    994     * @param nullValue  the value to return if {@code null}, may be {@code null}
    995     * @return the appropriate value
    996     */
    997    public static Integer toIntegerObject(final Boolean bool, final Integer trueValue, final Integer falseValue, final Integer nullValue) {
    998        if (bool == null) {
    999            return nullValue;
    1000        }
    1001        return bool.booleanValue() ? trueValue : falseValue;
    1002    }
    1003
    1004    /**
    1005     * Converts a boolean to a String returning one of the input Strings.
    1006     *
    1007     * <pre>
    1008     *   BooleanUtils.toString(true, "true", "false")   = "true"
    1009     *   BooleanUtils.toString(false, "true", "false")  = "false"
    1010     * </pre>
    1011     *
    1012     * @param bool  the Boolean to check
    1013     * @param trueString  the String to return if {@code true}, may be {@code null}
    1014     * @param falseString  the String to return if {@code false}, may be {@code null}
    1015     * @return one of the two input Strings
    1016     */
    1017    public static String toString(final boolean bool, final String trueString, final String falseString) {
    1018        return bool ? trueString : falseString;
    1019    }
    1020
    1021    /**
    1022     * Converts a Boolean to a String returning one of the input Strings.
    1023     *
    1024     * <pre>
    1025     *   BooleanUtils.toString(Boolean.TRUE, "true", "false", null)   = "true"
    1026     *   BooleanUtils.toString(Boolean.FALSE, "true", "false", null)  = "false"
    1027     *   BooleanUtils.toString(null, "true", "false", null)           = null;
    1028     * </pre>
    1029     *
    1030     * @param bool  the Boolean to check
    1031     * @param trueString  the String to return if {@code true}, may be {@code null}
    1032     * @param falseString  the String to return if {@code false}, may be {@code null}
    1033     * @param nullString  the String to return if {@code null}, may be {@code null}
    1034     * @return one of the three input Strings
    1035     */
    1036    public static String toString(final Boolean bool, final String trueString, final String falseString, final String nullString) {
    1037        if (bool == null) {
    1038            return nullString;
    1039        }
    1040        return bool.booleanValue() ? trueString : falseString;
    1041    }
    1042
    1043    /**
    1044     * Converts a boolean to a String returning {@code 'on'}
    1045     * or {@code 'off'}.
    1046     *
    1047     * <pre>
    1048     *   BooleanUtils.toStringOnOff(true)   = "on"
    1049     *   BooleanUtils.toStringOnOff(false)  = "off"
    1050     * </pre>
    1051     *
    1052     * @param bool  the Boolean to check
    1053     * @return {@code 'on'}, {@code 'off'}, or {@code null}
    1054     */
    1055    public static String toStringOnOff(final boolean bool) {
    1056        return toString(bool, ON, OFF);
    1057    }
    1058
    1059    /**
    1060     * Converts a Boolean to a String returning {@code 'on'},
    1061     * {@code 'off'}, or {@code null}.
    1062     *
    1063     * <pre>
    1064     *   BooleanUtils.toStringOnOff(Boolean.TRUE)  = "on"
    1065     *   BooleanUtils.toStringOnOff(Boolean.FALSE) = "off"
    1066     *   BooleanUtils.toStringOnOff(null)          = null;
    1067     * </pre>
    1068     *
    1069     * @param bool  the Boolean to check
    1070     * @return {@code 'on'}, {@code 'off'}, or {@code null}
    1071     */
    1072    public static String toStringOnOff(final Boolean bool) {
    1073        return toString(bool, ON, OFF, null);
    1074    }
    1075
    1076    /**
    1077     * Converts a boolean to a String returning {@code 'true'}
    1078     * or {@code 'false'}.
    1079     *
    1080     * <pre>
    1081     *   BooleanUtils.toStringTrueFalse(true)   = "true"
    1082     *   BooleanUtils.toStringTrueFalse(false)  = "false"
    1083     * </pre>
    1084     *
    1085     * @param bool  the Boolean to check
    1086     * @return {@code 'true'}, {@code 'false'}, or {@code null}
    1087     */
    1088    public static String toStringTrueFalse(final boolean bool) {
    1089        return toString(bool, TRUE, FALSE);
    1090    }
    1091
    1092    /**
    1093     * Converts a Boolean to a String returning {@code 'true'},
    1094     * {@code 'false'}, or {@code null}.
    1095     *
    1096     * <pre>
    1097     *   BooleanUtils.toStringTrueFalse(Boolean.TRUE)  = "true"
    1098     *   BooleanUtils.toStringTrueFalse(Boolean.FALSE) = "false"
    1099     *   BooleanUtils.toStringTrueFalse(null)          = null;
    1100     * </pre>
    1101     *
    1102     * @param bool  the Boolean to check
    1103     * @return {@code 'true'}, {@code 'false'}, or {@code null}
    1104     */
    1105    public static String toStringTrueFalse(final Boolean bool) {
    1106        return toString(bool, TRUE, FALSE, null);
    1107    }
    1108
    1109    /**
    1110     * Converts a boolean to a String returning {@code 'yes'}
    1111     * or {@code 'no'}.
    1112     *
    1113     * <pre>
    1114     *   BooleanUtils.toStringYesNo(true)   = "yes"
    1115     *   BooleanUtils.toStringYesNo(false)  = "no"
    1116     * </pre>
    1117     *
    1118     * @param bool  the Boolean to check
    1119     * @return {@code 'yes'}, {@code 'no'}, or {@code null}
    1120     */
    1121    public static String toStringYesNo(final boolean bool) {
    1122        return toString(bool, YES, NO);
    1123    }
    1124
    1125    /**
    1126     * Converts a Boolean to a String returning {@code 'yes'},
    1127     * {@code 'no'}, or {@code null}.
    1128     *
    1129     * <pre>
    1130     *   BooleanUtils.toStringYesNo(Boolean.TRUE)  = "yes"
    1131     *   BooleanUtils.toStringYesNo(Boolean.FALSE) = "no"
    1132     *   BooleanUtils.toStringYesNo(null)          = null;
    1133     * </pre>
    1134     *
    1135     * @param bool  the Boolean to check
    1136     * @return {@code 'yes'}, {@code 'no'}, or {@code null}
    1137     */
    1138    public static String toStringYesNo(final Boolean bool) {
    1139        return toString(bool, YES, NO, null);
    1140    }
    1141
    1142    /**
    1143     * Returns an unmodifiable list of Booleans {@code [false, true]}.
    1144     *
    1145     * @return an unmodifiable list of Booleans {@code [false, true]}.
    1146     * @since 3.13.0
    1147     */
    1148    public static List<Boolean> values() {
    1149        return BOOLEAN_LIST;
    1150    }
    1151
    1152    /**
    1153     * Performs an xor on a set of booleans.
    1154     * <p>
    1155     *   This behaves like an XOR gate;
    1156     *   it returns true if the number of true values is odd,
    1157     *   and false if the number of true values is zero or even.
    1158     * </p>
    1159     *
    1160     * <pre>
    1161     *   BooleanUtils.xor(true, true)             = false
    1162     *   BooleanUtils.xor(false, false)           = false
    1163     *   BooleanUtils.xor(true, false)            = true
    1164     *   BooleanUtils.xor(true, false, false)     = true
    1165     *   BooleanUtils.xor(true, true, true)       = true
    1166     *   BooleanUtils.xor(true, true, true, true) = false
    1167     * </pre>
    1168     *
    1169     * @param array  an array of {@code boolean}s
    1170     * @return true if the number of true values in the array is odd; otherwise returns false.
    1171     * @throws NullPointerException if {@code array} is {@code null}
    1172     * @throws IllegalArgumentException if {@code array} is empty.
    1173     */
    1174    public static boolean xor(final boolean... array) {
    1175        ObjectUtils.requireNonEmpty(array, "array");
    1176        // false if the neutral element of the xor operator
    1177        boolean result = false;
    1178        for (final boolean element : array) {
    1179            result ^= element;
    1180        }
    1181
    1182        return result;
    1183    }
    1184
    1185    /**
    1186     * Performs an xor on an array of Booleans.
    1187     * <pre>
    1188     *   BooleanUtils.xor(Boolean.TRUE, Boolean.TRUE)                 = Boolean.FALSE
    1189     *   BooleanUtils.xor(Boolean.FALSE, Boolean.FALSE)               = Boolean.FALSE
    1190     *   BooleanUtils.xor(Boolean.TRUE, Boolean.FALSE)                = Boolean.TRUE
    1191     *   BooleanUtils.xor(Boolean.TRUE, Boolean.FALSE, Boolean.FALSE) = Boolean.TRUE
    1192     *   BooleanUtils.xor(Boolean.FALSE, null)                        = Boolean.FALSE
    1193     *   BooleanUtils.xor(Boolean.TRUE, null)                         = Boolean.TRUE
    1194     * </pre>
    1195     * <p>
    1196     * Null array elements map to false, like {@code Boolean.parseBoolean(null)} and its callers return false.
    1197     * </p>
    1198     *
    1199     * @param array  an array of {@link Boolean}s
    1200     * @return the result of the xor operations
    1201     * @throws NullPointerException if {@code array} is {@code null}
    1202     * @throws IllegalArgumentException if {@code array} is empty.
    1203     */
    1204    public static Boolean xor(final Boolean... array) {
    1205        ObjectUtils.requireNonEmpty(array, "array");
    1206        return xor(ArrayUtils.toPrimitive(array)) ? Boolean.TRUE : Boolean.FALSE;
    1207    }
    1208
    1209    /**
    1210     * {@link BooleanUtils} instances should NOT be constructed in standard programming.
    1211     * Instead, the class should be used as {@code BooleanUtils.negate(true);}.
    1212     *
    1213     * <p>This constructor is public to permit tools that require a JavaBean instance
    1214     * to operate.</p>
    1215     */
    1216    public BooleanUtils() {
    1217    }
    1218
    1219}