    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.lang.reflect.Array;
    020import java.lang.reflect.Field;
    021import java.lang.reflect.Method;
    022import java.lang.reflect.Type;
    023import java.util.Arrays;
    024import java.util.BitSet;
    025import java.util.Comparator;
    026import java.util.Date;
    027import java.util.HashMap;
    028import java.util.Map;
    029import java.util.Objects;
    030import java.util.Random;
    031import java.util.concurrent.ThreadLocalRandom;
    032import java.util.function.IntFunction;
    033import java.util.function.Supplier;
    034
    035import org.apache.commons.lang3.builder.EqualsBuilder;
    036import org.apache.commons.lang3.builder.HashCodeBuilder;
    037import org.apache.commons.lang3.builder.ToStringBuilder;
    038import org.apache.commons.lang3.builder.ToStringStyle;
    039import org.apache.commons.lang3.math.NumberUtils;
    040import org.apache.commons.lang3.mutable.MutableInt;
    041import org.apache.commons.lang3.stream.Streams;
    042
    043/**
    044 * Operations on arrays, primitive arrays (like {@code int[]}) and
    045 * primitive wrapper arrays (like {@code Integer[]}).
    046 * <p>
    047 * This class tries to handle {@code null} input gracefully.
    048 * An exception will not be thrown for a {@code null}
    049 * array input. However, an Object array that contains a {@code null}
    050 * element may throw an exception. Each method documents its behavior.
    051 * </p>
    052 * <p>
    053 * #ThreadSafe#
    054 * </p>
    055 * @since 2.0
    056 */
    057public class ArrayUtils {
    058
    059    /**
    060     * An empty immutable {@code boolean} array.
    061     */
    062    public static final boolean[] EMPTY_BOOLEAN_ARRAY = {};
    063
    064    /**
    065     * An empty immutable {@link Boolean} array.
    066     */
    067    public static final Boolean[] EMPTY_BOOLEAN_OBJECT_ARRAY = {};
    068
    069    /**
    070     * An empty immutable {@code byte} array.
    071     */
    072    public static final byte[] EMPTY_BYTE_ARRAY = {};
    073
    074    /**
    075     * An empty immutable {@link Byte} array.
    076     */
    077    public static final Byte[] EMPTY_BYTE_OBJECT_ARRAY = {};
    078
    079    /**
    080     * An empty immutable {@code char} array.
    081     */
    082    public static final char[] EMPTY_CHAR_ARRAY = {};
    083
    084    /**
    085     * An empty immutable {@link Character} array.
    086     */
    087    public static final Character[] EMPTY_CHARACTER_OBJECT_ARRAY = {};
    088
    089    /**
    090     * An empty immutable {@link Class} array.
    091     */
    092    public static final Class<?>[] EMPTY_CLASS_ARRAY = {};
    093
    094    /**
    095     * An empty immutable {@code double} array.
    096     */
    097    public static final double[] EMPTY_DOUBLE_ARRAY = {};
    098
    099    /**
    100     * An empty immutable {@link Double} array.
    101     */
    102    public static final Double[] EMPTY_DOUBLE_OBJECT_ARRAY = {};
    103
    104    /**
    105     * An empty immutable {@link Field} array.
    106     *
    107     * @since 3.10
    108     */
    109    public static final Field[] EMPTY_FIELD_ARRAY = {};
    110
    111    /**
    112     * An empty immutable {@code float} array.
    113     */
    114    public static final float[] EMPTY_FLOAT_ARRAY = {};
    115
    116    /**
    117     * An empty immutable {@link Float} array.
    118     */
    119    public static final Float[] EMPTY_FLOAT_OBJECT_ARRAY = {};
    120
    121    /**
    122     * An empty immutable {@code int} array.
    123     */
    124    public static final int[] EMPTY_INT_ARRAY = {};
    125
    126    /**
    127     * An empty immutable {@link Integer} array.
    128     */
    129    public static final Integer[] EMPTY_INTEGER_OBJECT_ARRAY = {};
    130
    131    /**
    132     * An empty immutable {@code long} array.
    133     */
    134    public static final long[] EMPTY_LONG_ARRAY = {};
    135
    136    /**
    137     * An empty immutable {@link Long} array.
    138     */
    139    public static final Long[] EMPTY_LONG_OBJECT_ARRAY = {};
    140
    141    /**
    142     * An empty immutable {@link Method} array.
    143     *
    144     * @since 3.10
    145     */
    146    public static final Method[] EMPTY_METHOD_ARRAY = {};
    147
    148    /**
    149     * An empty immutable {@link Object} array.
    150     */
    151    public static final Object[] EMPTY_OBJECT_ARRAY = {};
    152
    153    /**
    154     * An empty immutable {@code short} array.
    155     */
    156    public static final short[] EMPTY_SHORT_ARRAY = {};
    157
    158    /**
    159     * An empty immutable {@link Short} array.
    160     */
    161    public static final Short[] EMPTY_SHORT_OBJECT_ARRAY = {};
    162
    163    /**
    164     * An empty immutable {@link String} array.
    165     */
    166    public static final String[] EMPTY_STRING_ARRAY = {};
    167
    168    /**
    169     * An empty immutable {@link Throwable} array.
    170     *
    171     * @since 3.10
    172     */
    173    public static final Throwable[] EMPTY_THROWABLE_ARRAY = {};
    174
    175    /**
    176     * An empty immutable {@link Type} array.
    177     *
    178     * @since 3.10
    179     */
    180    public static final Type[] EMPTY_TYPE_ARRAY = {};
    181
    182    /**
    183     * The index value when an element is not found in a list or array: {@code -1}.
    184     * This value is returned by methods in this class and can also be used in comparisons with values returned by
    185     * various method from {@link java.util.List}.
    186     */
    187    public static final int INDEX_NOT_FOUND = -1;
    188
    189    /**
    190     * Copies the given array and adds the given element at the end of the new array.
    191     * <p>
    192     * The new array contains the same elements of the input
    193     * array plus the given element in the last position. The component type of
    194     * the new array is the same as that of the input array.
    195     * </p>
    196     * <p>
    197     * If the input array is {@code null}, a new one element array is returned
    198     * whose component type is the same as the element.
    199     * </p>
    200     * <pre>
    201     * ArrayUtils.add(null, true)          = [true]
    202     * ArrayUtils.add([true], false)       = [true, false]
    203     * ArrayUtils.add([true, false], true) = [true, false, true]
    204     * </pre>
    205     *
    206     * @param array  the array to copy and add the element to, may be {@code null}
    207     * @param element  the object to add at the last index of the new array
    208     * @return A new array containing the existing elements plus the new element
    209     * @since 2.1
    210     */
    211    public static boolean[] add(final boolean[] array, final boolean element) {
    212        final boolean[] newArray = (boolean[]) copyArrayGrow1(array, Boolean.TYPE);
    213        newArray[newArray.length - 1] = element;
    214        return newArray;
    215    }
    216
    217    /**
    218     * Inserts the specified element at the specified position in the array.
    219     * Shifts the element currently at that position (if any) and any subsequent
    220     * elements to the right (adds one to their indices).
    221     * <p>
    222     * This method returns a new array with the same elements of the input
    223     * array plus the given element on the specified position. The component
    224     * type of the returned array is always the same as that of the input
    225     * array.
    226     * </p>
    227     * <p>
    228     * If the input array is {@code null}, a new one element array is returned
    229     * whose component type is the same as the element.
    230     * </p>
    231     * <pre>
    232     * ArrayUtils.add(null, 0, true)          = [true]
    233     * ArrayUtils.add([true], 0, false)       = [false, true]
    234     * ArrayUtils.add([false], 1, true)       = [false, true]
    235     * ArrayUtils.add([true, false], 1, true) = [true, true, false]
    236     * </pre>
    237     *
    238     * @param array  the array to add the element to, may be {@code null}
    239     * @param index  the position of the new object
    240     * @param element  the object to add
    241     * @return A new array containing the existing elements and the new element
    242     * @throws IndexOutOfBoundsException if the index is out of range (index &lt; 0 || index &gt; array.length).
    243     * @deprecated this method has been superseded by {@link #insert(int, boolean[], boolean...)} and
    244     * may be removed in a future release. Please note the handling of {@code null} input arrays differs
    245     * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
    246     */
    247    @Deprecated
    248    public static boolean[] add(final boolean[] array, final int index, final boolean element) {
    249        return (boolean[]) add(array, index, Boolean.valueOf(element), Boolean.TYPE);
    250    }
    251
    252    /**
    253     * Copies the given array and adds the given element at the end of the new array.
    254     * <p>
    255     * The new array contains the same elements of the input
    256     * array plus the given element in the last position. The component type of
    257     * the new array is the same as that of the input array.
    258     * </p>
    259     * <p>
    260     * If the input array is {@code null}, a new one element array is returned
    261     * whose component type is the same as the element.
    262     * </p>
    263     * <pre>
    264     * ArrayUtils.add(null, 0)   = [0]
    265     * ArrayUtils.add([1], 0)    = [1, 0]
    266     * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
    267     * </pre>
    268     *
    269     * @param array  the array to copy and add the element to, may be {@code null}
    270     * @param element  the object to add at the last index of the new array
    271     * @return A new array containing the existing elements plus the new element
    272     * @since 2.1
    273     */
    274    public static byte[] add(final byte[] array, final byte element) {
    275        final byte[] newArray = (byte[]) copyArrayGrow1(array, Byte.TYPE);
    276        newArray[newArray.length - 1] = element;
    277        return newArray;
    278    }
    279
    280    /**
    281     * Inserts the specified element at the specified position in the array.
    282     * Shifts the element currently at that position (if any) and any subsequent
    283     * elements to the right (adds one to their indices).
    284     * <p>
    285     * This method returns a new array with the same elements of the input
    286     * array plus the given element on the specified position. The component
    287     * type of the returned array is always the same as that of the input
    288     * array.
    289     * </p>
    290     * <p>
    291     * If the input array is {@code null}, a new one element array is returned
    292     * whose component type is the same as the element.
    293     * </p>
    294     * <pre>
    295     * ArrayUtils.add([1], 0, 2)         = [2, 1]
    296     * ArrayUtils.add([2, 6], 2, 3)      = [2, 6, 3]
    297     * ArrayUtils.add([2, 6], 0, 1)      = [1, 2, 6]
    298     * ArrayUtils.add([2, 6, 3], 2, 1)   = [2, 6, 1, 3]
    299     * </pre>
    300     *
    301     * @param array  the array to add the element to, may be {@code null}
    302     * @param index  the position of the new object
    303     * @param element  the object to add
    304     * @return A new array containing the existing elements and the new element
    305     * @throws IndexOutOfBoundsException if the index is out of range
    306     * (index &lt; 0 || index &gt; array.length).
    307     * @deprecated this method has been superseded by {@link #insert(int, byte[], byte...)} and
    308     * may be removed in a future release. Please note the handling of {@code null} input arrays differs
    309     * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
    310     */
    311    @Deprecated
    312    public static byte[] add(final byte[] array, final int index, final byte element) {
    313        return (byte[]) add(array, index, Byte.valueOf(element), Byte.TYPE);
    314    }
    315
    316    /**
    317     * Copies the given array and adds the given element at the end of the new array.
    318     * <p>
    319     * The new array contains the same elements of the input
    320     * array plus the given element in the last position. The component type of
    321     * the new array is the same as that of the input array.
    322     * </p>
    323     * <p>
    324     * If the input array is {@code null}, a new one element array is returned
    325     * whose component type is the same as the element.
    326     * </p>
    327     * <pre>
    328     * ArrayUtils.add(null, '0')       = ['0']
    329     * ArrayUtils.add(['1'], '0')      = ['1', '0']
    330     * ArrayUtils.add(['1', '0'], '1') = ['1', '0', '1']
    331     * </pre>
    332     *
    333     * @param array  the array to copy and add the element to, may be {@code null}
    334     * @param element  the object to add at the last index of the new array
    335     * @return A new array containing the existing elements plus the new element
    336     * @since 2.1
    337     */
    338    public static char[] add(final char[] array, final char element) {
    339        final char[] newArray = (char[]) copyArrayGrow1(array, Character.TYPE);
    340        newArray[newArray.length - 1] = element;
    341        return newArray;
    342    }
    343
    344    /**
    345     * Inserts the specified element at the specified position in the array.
    346     * Shifts the element currently at that position (if any) and any subsequent
    347     * elements to the right (adds one to their indices).
    348     * <p>
    349     * This method returns a new array with the same elements of the input
    350     * array plus the given element on the specified position. The component
    351     * type of the returned array is always the same as that of the input
    352     * array.
    353     * </p>
    354     * <p>
    355     * If the input array is {@code null}, a new one element array is returned
    356     * whose component type is the same as the element.
    357     * </p>
    358     * <pre>
    359     * ArrayUtils.add(null, 0, 'a')            = ['a']
    360     * ArrayUtils.add(['a'], 0, 'b')           = ['b', 'a']
    361     * ArrayUtils.add(['a', 'b'], 0, 'c')      = ['c', 'a', 'b']
    362     * ArrayUtils.add(['a', 'b'], 1, 'k')      = ['a', 'k', 'b']
    363     * ArrayUtils.add(['a', 'b', 'c'], 1, 't') = ['a', 't', 'b', 'c']
    364     * </pre>
    365     *
    366     * @param array  the array to add the element to, may be {@code null}
    367     * @param index  the position of the new object
    368     * @param element  the object to add
    369     * @return A new array containing the existing elements and the new element
    370     * @throws IndexOutOfBoundsException if the index is out of range
    371     * (index &lt; 0 || index &gt; array.length).
    372     * @deprecated this method has been superseded by {@link #insert(int, char[], char...)} and
    373     * may be removed in a future release. Please note the handling of {@code null} input arrays differs
    374     * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
    375     */
    376    @Deprecated
    377    public static char[] add(final char[] array, final int index, final char element) {
    378        return (char[]) add(array, index, Character.valueOf(element), Character.TYPE);
    379    }
    380
    381    /**
    382     * Copies the given array and adds the given element at the end of the new array.
    383     *
    384     * <p>
    385     * The new array contains the same elements of the input
    386     * array plus the given element in the last position. The component type of
    387     * the new array is the same as that of the input array.
    388     * </p>
    389     * <p>
    390     * If the input array is {@code null}, a new one element array is returned
    391     * whose component type is the same as the element.
    392     * </p>
    393     * <pre>
    394     * ArrayUtils.add(null, 0)   = [0]
    395     * ArrayUtils.add([1], 0)    = [1, 0]
    396     * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
    397     * </pre>
    398     *
    399     * @param array  the array to copy and add the element to, may be {@code null}
    400     * @param element  the object to add at the last index of the new array
    401     * @return A new array containing the existing elements plus the new element
    402     * @since 2.1
    403     */
    404    public static double[] add(final double[] array, final double element) {
    405        final double[] newArray = (double[]) copyArrayGrow1(array, Double.TYPE);
    406        newArray[newArray.length - 1] = element;
    407        return newArray;
    408    }
    409
    410    /**
    411     * Inserts the specified element at the specified position in the array.
    412     * Shifts the element currently at that position (if any) and any subsequent
    413     * elements to the right (adds one to their indices).
    414     * <p>
    415     * This method returns a new array with the same elements of the input
    416     * array plus the given element on the specified position. The component
    417     * type of the returned array is always the same as that of the input
    418     * array.
    419     * </p>
    420     * <p>
    421     * If the input array is {@code null}, a new one element array is returned
    422     * whose component type is the same as the element.
    423     * </p>
    424     * <pre>
    425     * ArrayUtils.add([1.1], 0, 2.2)              = [2.2, 1.1]
    426     * ArrayUtils.add([2.3, 6.4], 2, 10.5)        = [2.3, 6.4, 10.5]
    427     * ArrayUtils.add([2.6, 6.7], 0, -4.8)        = [-4.8, 2.6, 6.7]
    428     * ArrayUtils.add([2.9, 6.0, 0.3], 2, 1.0)    = [2.9, 6.0, 1.0, 0.3]
    429     * </pre>
    430     *
    431     * @param array  the array to add the element to, may be {@code null}
    432     * @param index  the position of the new object
    433     * @param element  the object to add
    434     * @return A new array containing the existing elements and the new element
    435     * @throws IndexOutOfBoundsException if the index is out of range
    436     * (index &lt; 0 || index &gt; array.length).
    437     * @deprecated this method has been superseded by {@link #insert(int, double[], double...)} and
    438     * may be removed in a future release. Please note the handling of {@code null} input arrays differs
    439     * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
    440     */
    441    @Deprecated
    442    public static double[] add(final double[] array, final int index, final double element) {
    443        return (double[]) add(array, index, Double.valueOf(element), Double.TYPE);
    444    }
    445
    446    /**
    447     * Copies the given array and adds the given element at the end of the new array.
    448     * <p>
    449     * The new array contains the same elements of the input
    450     * array plus the given element in the last position. The component type of
    451     * the new array is the same as that of the input array.
    452     * </p>
    453     * <p>
    454     * If the input array is {@code null}, a new one element array is returned
    455     * whose component type is the same as the element.
    456     * </p>
    457     * <pre>
    458     * ArrayUtils.add(null, 0)   = [0]
    459     * ArrayUtils.add([1], 0)    = [1, 0]
    460     * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
    461     * </pre>
    462     *
    463     * @param array  the array to copy and add the element to, may be {@code null}
    464     * @param element  the object to add at the last index of the new array
    465     * @return A new array containing the existing elements plus the new element
    466     * @since 2.1
    467     */
    468    public static float[] add(final float[] array, final float element) {
    469        final float[] newArray = (float[]) copyArrayGrow1(array, Float.TYPE);
    470        newArray[newArray.length - 1] = element;
    471        return newArray;
    472    }
    473
    474    /**
    475     * Inserts the specified element at the specified position in the array.
    476     * Shifts the element currently at that position (if any) and any subsequent
    477     * elements to the right (adds one to their indices).
    478     * <p>
    479     * This method returns a new array with the same elements of the input
    480     * array plus the given element on the specified position. The component
    481     * type of the returned array is always the same as that of the input
    482     * array.
    483     * </p>
    484     * <p>
    485     * If the input array is {@code null}, a new one element array is returned
    486     * whose component type is the same as the element.
    487     * </p>
    488     * <pre>
    489     * ArrayUtils.add([1.1f], 0, 2.2f)               = [2.2f, 1.1f]
    490     * ArrayUtils.add([2.3f, 6.4f], 2, 10.5f)        = [2.3f, 6.4f, 10.5f]
    491     * ArrayUtils.add([2.6f, 6.7f], 0, -4.8f)        = [-4.8f, 2.6f, 6.7f]
    492     * ArrayUtils.add([2.9f, 6.0f, 0.3f], 2, 1.0f)   = [2.9f, 6.0f, 1.0f, 0.3f]
    493     * </pre>
    494     *
    495     * @param array  the array to add the element to, may be {@code null}
    496     * @param index  the position of the new object
    497     * @param element  the object to add
    498     * @return A new array containing the existing elements and the new element
    499     * @throws IndexOutOfBoundsException if the index is out of range
    500     * (index &lt; 0 || index &gt; array.length).
    501     * @deprecated this method has been superseded by {@link #insert(int, float[], float...)} and
    502     * may be removed in a future release. Please note the handling of {@code null} input arrays differs
    503     * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
    504     */
    505    @Deprecated
    506    public static float[] add(final float[] array, final int index, final float element) {
    507        return (float[]) add(array, index, Float.valueOf(element), Float.TYPE);
    508    }
    509
    510    /**
    511     * Copies the given array and adds the given element at the end of the new array.
    512     * <p>
    513     * The new array contains the same elements of the input
    514     * array plus the given element in the last position. The component type of
    515     * the new array is the same as that of the input array.
    516     * </p>
    517     * <p>
    518     * If the input array is {@code null}, a new one element array is returned
    519     * whose component type is the same as the element.
    520     * </p>
    521     * <pre>
    522     * ArrayUtils.add(null, 0)   = [0]
    523     * ArrayUtils.add([1], 0)    = [1, 0]
    524     * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
    525     * </pre>
    526     *
    527     * @param array  the array to copy and add the element to, may be {@code null}
    528     * @param element  the object to add at the last index of the new array
    529     * @return A new array containing the existing elements plus the new element
    530     * @since 2.1
    531     */
    532    public static int[] add(final int[] array, final int element) {
    533        final int[] newArray = (int[]) copyArrayGrow1(array, Integer.TYPE);
    534        newArray[newArray.length - 1] = element;
    535        return newArray;
    536    }
    537
    538    /**
    539     * Inserts the specified element at the specified position in the array.
    540     * Shifts the element currently at that position (if any) and any subsequent
    541     * elements to the right (adds one to their indices).
    542     * <p>
    543     * This method returns a new array with the same elements of the input
    544     * array plus the given element on the specified position. The component
    545     * type of the returned array is always the same as that of the input
    546     * array.
    547     * </p>
    548     * <p>
    549     * If the input array is {@code null}, a new one element array is returned
    550     * whose component type is the same as the element.
    551     * </p>
    552     * <pre>
    553     * ArrayUtils.add([1], 0, 2)         = [2, 1]
    554     * ArrayUtils.add([2, 6], 2, 10)     = [2, 6, 10]
    555     * ArrayUtils.add([2, 6], 0, -4)     = [-4, 2, 6]
    556     * ArrayUtils.add([2, 6, 3], 2, 1)   = [2, 6, 1, 3]
    557     * </pre>
    558     *
    559     * @param array  the array to add the element to, may be {@code null}
    560     * @param index  the position of the new object
    561     * @param element  the object to add
    562     * @return A new array containing the existing elements and the new element
    563     * @throws IndexOutOfBoundsException if the index is out of range
    564     * (index &lt; 0 || index &gt; array.length).
    565     * @deprecated this method has been superseded by {@link #insert(int, int[], int...)} and
    566     * may be removed in a future release. Please note the handling of {@code null} input arrays differs
    567     * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
    568     */
    569    @Deprecated
    570    public static int[] add(final int[] array, final int index, final int element) {
    571        return (int[]) add(array, index, Integer.valueOf(element), Integer.TYPE);
    572    }
    573
    574    /**
    575     * Inserts the specified element at the specified position in the array.
    576     * Shifts the element currently at that position (if any) and any subsequent
    577     * elements to the right (adds one to their indices).
    578     * <p>
    579     * This method returns a new array with the same elements of the input
    580     * array plus the given element on the specified position. The component
    581     * type of the returned array is always the same as that of the input
    582     * array.
    583     * </p>
    584     * <p>
    585     * If the input array is {@code null}, a new one element array is returned
    586     * whose component type is the same as the element.
    587     * </p>
    588     * <pre>
    589     * ArrayUtils.add([1L], 0, 2L)           = [2L, 1L]
    590     * ArrayUtils.add([2L, 6L], 2, 10L)      = [2L, 6L, 10L]
    591     * ArrayUtils.add([2L, 6L], 0, -4L)      = [-4L, 2L, 6L]
    592     * ArrayUtils.add([2L, 6L, 3L], 2, 1L)   = [2L, 6L, 1L, 3L]
    593     * </pre>
    594     *
    595     * @param array  the array to add the element to, may be {@code null}
    596     * @param index  the position of the new object
    597     * @param element  the object to add
    598     * @return A new array containing the existing elements and the new element
    599     * @throws IndexOutOfBoundsException if the index is out of range
    600     * (index &lt; 0 || index &gt; array.length).
    601     * @deprecated this method has been superseded by {@link #insert(int, long[], long...)} and
    602     * may be removed in a future release. Please note the handling of {@code null} input arrays differs
    603     * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
    604     */
    605    @Deprecated
    606    public static long[] add(final long[] array, final int index, final long element) {
    607        return (long[]) add(array, index, Long.valueOf(element), Long.TYPE);
    608    }
    609
    610    /**
    611     * Copies the given array and adds the given element at the end of the new array.
    612     * <p>
    613     * The new array contains the same elements of the input
    614     * array plus the given element in the last position. The component type of
    615     * the new array is the same as that of the input array.
    616     * </p>
    617     * <p>
    618     * If the input array is {@code null}, a new one element array is returned
    619     * whose component type is the same as the element.
    620     * </p>
    621     * <pre>
    622     * ArrayUtils.add(null, 0)   = [0]
    623     * ArrayUtils.add([1], 0)    = [1, 0]
    624     * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
    625     * </pre>
    626     *
    627     * @param array  the array to copy and add the element to, may be {@code null}
    628     * @param element  the object to add at the last index of the new array
    629     * @return A new array containing the existing elements plus the new element
    630     * @since 2.1
    631     */
    632    public static long[] add(final long[] array, final long element) {
    633        final long[] newArray = (long[]) copyArrayGrow1(array, Long.TYPE);
    634        newArray[newArray.length - 1] = element;
    635        return newArray;
    636    }
    637
    638    /**
    639     * Underlying implementation of add(array, index, element) methods.
    640     * The last parameter is the class, which may not equal element.getClass
    641     * for primitives.
    642     *
    643     * @param array  the array to add the element to, may be {@code null}
    644     * @param index  the position of the new object
    645     * @param element  the object to add
    646     * @param clss the type of the element being added
    647     * @return A new array containing the existing elements and the new element
    648     */
    649    private static Object add(final Object array, final int index, final Object element, final Class<?> clss) {
    650        if (array == null) {
    651            if (index != 0) {
    652                throw new IndexOutOfBoundsException("Index: " + index + ", Length: 0");
    653            }
    654            final Object joinedArray = Array.newInstance(clss, 1);
    655            Array.set(joinedArray, 0, element);
    656            return joinedArray;
    657        }
    658        final int length = Array.getLength(array);
    659        if (index > length || index < 0) {
    660            throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + length);
    661        }
    662        final Object result = Array.newInstance(clss, length + 1);
    663        System.arraycopy(array, 0, result, 0, index);
    664        Array.set(result, index, element);
    665        if (index < length) {
    666            System.arraycopy(array, index, result, index + 1, length - index);
    667        }
    668        return result;
    669    }
    670
    671    /**
    672     * Inserts the specified element at the specified position in the array.
    673     * Shifts the element currently at that position (if any) and any subsequent
    674     * elements to the right (adds one to their indices).
    675     * <p>
    676     * This method returns a new array with the same elements of the input
    677     * array plus the given element on the specified position. The component
    678     * type of the returned array is always the same as that of the input
    679     * array.
    680     * </p>
    681     * <p>
    682     * If the input array is {@code null}, a new one element array is returned
    683     * whose component type is the same as the element.
    684     * </p>
    685     * <pre>
    686     * ArrayUtils.add([1], 0, 2)         = [2, 1]
    687     * ArrayUtils.add([2, 6], 2, 10)     = [2, 6, 10]
    688     * ArrayUtils.add([2, 6], 0, -4)     = [-4, 2, 6]
    689     * ArrayUtils.add([2, 6, 3], 2, 1)   = [2, 6, 1, 3]
    690     * </pre>
    691     *
    692     * @param array  the array to add the element to, may be {@code null}
    693     * @param index  the position of the new object
    694     * @param element  the object to add
    695     * @return A new array containing the existing elements and the new element
    696     * @throws IndexOutOfBoundsException if the index is out of range
    697     * (index &lt; 0 || index &gt; array.length).
    698     * @deprecated this method has been superseded by {@link #insert(int, short[], short...)} and
    699     * may be removed in a future release. Please note the handling of {@code null} input arrays differs
    700     * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
    701     */
    702    @Deprecated
    703    public static short[] add(final short[] array, final int index, final short element) {
    704        return (short[]) add(array, index, Short.valueOf(element), Short.TYPE);
    705    }
    706
    707    /**
    708     * Copies the given array and adds the given element at the end of the new array.
    709     * <p>
    710     * The new array contains the same elements of the input
    711     * array plus the given element in the last position. The component type of
    712     * the new array is the same as that of the input array.
    713     * </p>
    714     * <p>
    715     * If the input array is {@code null}, a new one element array is returned
    716     * whose component type is the same as the element.
    717     * </p>
    718     * <pre>
    719     * ArrayUtils.add(null, 0)   = [0]
    720     * ArrayUtils.add([1], 0)    = [1, 0]
    721     * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
    722     * </pre>
    723     *
    724     * @param array  the array to copy and add the element to, may be {@code null}
    725     * @param element  the object to add at the last index of the new array
    726     * @return A new array containing the existing elements plus the new element
    727     * @since 2.1
    728     */
    729    public static short[] add(final short[] array, final short element) {
    730        final short[] newArray = (short[]) copyArrayGrow1(array, Short.TYPE);
    731        newArray[newArray.length - 1] = element;
    732        return newArray;
    733    }
    734
    735    /**
    736     * Inserts the specified element at the specified position in the array.
    737     * Shifts the element currently at that position (if any) and any subsequent
    738     * elements to the right (adds one to their indices).
    739     * <p>
    740     * This method returns a new array with the same elements of the input
    741     * array plus the given element on the specified position. The component
    742     * type of the returned array is always the same as that of the input
    743     * array.
    744     * </p>
    745     * <p>
    746     * If the input array is {@code null}, a new one element array is returned
    747     * whose component type is the same as the element.
    748     * </p>
    749     * <pre>
    750     * ArrayUtils.add(null, 0, null)      = IllegalArgumentException
    751     * ArrayUtils.add(null, 0, "a")       = ["a"]
    752     * ArrayUtils.add(["a"], 1, null)     = ["a", null]
    753     * ArrayUtils.add(["a"], 1, "b")      = ["a", "b"]
    754     * ArrayUtils.add(["a", "b"], 3, "c") = ["a", "b", "c"]
    755     * </pre>
    756     *
    757     * @param <T> the component type of the array
    758     * @param array  the array to add the element to, may be {@code null}
    759     * @param index  the position of the new object
    760     * @param element  the object to add
    761     * @return A new array containing the existing elements and the new element
    762     * @throws IndexOutOfBoundsException if the index is out of range (index &lt; 0 || index &gt; array.length).
    763     * @throws IllegalArgumentException if both array and element are null
    764     * @deprecated this method has been superseded by {@link #insert(int, Object[], Object...) insert(int, T[], T...)} and
    765     * may be removed in a future release. Please note the handling of {@code null} input arrays differs
    766     * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
    767     */
    768    @Deprecated
    769    public static <T> T[] add(final T[] array, final int index, final T element) {
    770        final Class<T> clss;
    771        if (array != null) {
    772            clss = getComponentType(array);
    773        } else if (element != null) {
    774            clss = ObjectUtils.getClass(element);
    775        } else {
    776            throw new IllegalArgumentException("Array and element cannot both be null");
    777        }
    778        return (T[]) add(array, index, element, clss);
    779    }
    780
    781
    782    /**
    783     * Copies the given array and adds the given element at the end of the new array.
    784     * <p>
    785     * The new array contains the same elements of the input
    786     * array plus the given element in the last position. The component type of
    787     * the new array is the same as that of the input array.
    788     * </p>
    789     * <p>
    790     * If the input array is {@code null}, a new one element array is returned
    791     * whose component type is the same as the element, unless the element itself is null,
    792     * in which case the return type is Object[]
    793     * </p>
    794     * <pre>
    795     * ArrayUtils.add(null, null)      = IllegalArgumentException
    796     * ArrayUtils.add(null, "a")       = ["a"]
    797     * ArrayUtils.add(["a"], null)     = ["a", null]
    798     * ArrayUtils.add(["a"], "b")      = ["a", "b"]
    799     * ArrayUtils.add(["a", "b"], "c") = ["a", "b", "c"]
    800     * </pre>
    801     *
    802     * @param <T> the component type of the array
    803     * @param array  the array to "add" the element to, may be {@code null}
    804     * @param element  the object to add, may be {@code null}
    805     * @return A new array containing the existing elements plus the new element
    806     * The returned array type will be that of the input array (unless null),
    807     * in which case it will have the same type as the element.
    808     * If both are null, an IllegalArgumentException is thrown
    809     * @since 2.1
    810     * @throws IllegalArgumentException if both arguments are null
    811     */
    812    public static <T> T[] add(final T[] array, final T element) {
    813        final Class<?> type;
    814        if (array != null) {
    815            type = array.getClass().getComponentType();
    816        } else if (element != null) {
    817            type = element.getClass();
    818        } else {
    819            throw new IllegalArgumentException("Arguments cannot both be null");
    820        }
    821        @SuppressWarnings("unchecked") // type must be T
    822        final
    823        T[] newArray = (T[]) copyArrayGrow1(array, type);
    824        newArray[newArray.length - 1] = element;
    825        return newArray;
    826    }
    827
    828    /**
    829     * Adds all the elements of the given arrays into a new array.
    830     * <p>
    831     * The new array contains all of the element of {@code array1} followed
    832     * by all of the elements {@code array2}. When an array is returned, it is always
    833     * a new array.
    834     * </p>
    835     * <pre>
    836     * ArrayUtils.addAll(array1, null)   = cloned copy of array1
    837     * ArrayUtils.addAll(null, array2)   = cloned copy of array2
    838     * ArrayUtils.addAll([], [])         = []
    839     * </pre>
    840     *
    841     * @param array1  the first array whose elements are added to the new array.
    842     * @param array2  the second array whose elements are added to the new array.
    843     * @return The new boolean[] array.
    844     * @since 2.1
    845     */
    846    public static boolean[] addAll(final boolean[] array1, final boolean... array2) {
    847        if (array1 == null) {
    848            return clone(array2);
    849        }
    850        if (array2 == null) {
    851            return clone(array1);
    852        }
    853        final boolean[] joinedArray = new boolean[array1.length + array2.length];
    854        System.arraycopy(array1, 0, joinedArray, 0, array1.length);
    855        System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
    856        return joinedArray;
    857    }
    858
    859    /**
    860     * Adds all the elements of the given arrays into a new array.
    861     * <p>
    862     * The new array contains all of the element of {@code array1} followed
    863     * by all of the elements {@code array2}. When an array is returned, it is always
    864     * a new array.
    865     * </p>
    866     * <pre>
    867     * ArrayUtils.addAll(array1, null)   = cloned copy of array1
    868     * ArrayUtils.addAll(null, array2)   = cloned copy of array2
    869     * ArrayUtils.addAll([], [])         = []
    870     * </pre>
    871     *
    872     * @param array1  the first array whose elements are added to the new array.
    873     * @param array2  the second array whose elements are added to the new array.
    874     * @return The new byte[] array.
    875     * @since 2.1
    876     */
    877    public static byte[] addAll(final byte[] array1, final byte... array2) {
    878        if (array1 == null) {
    879            return clone(array2);
    880        }
    881        if (array2 == null) {
    882            return clone(array1);
    883        }
    884        final byte[] joinedArray = new byte[array1.length + array2.length];
    885        System.arraycopy(array1, 0, joinedArray, 0, array1.length);
    886        System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
    887        return joinedArray;
    888    }
    889
    890    /**
    891     * Adds all the elements of the given arrays into a new array.
    892     * <p>
    893     * The new array contains all of the element of {@code array1} followed
    894     * by all of the elements {@code array2}. When an array is returned, it is always
    895     * a new array.
    896     * </p>
    897     * <pre>
    898     * ArrayUtils.addAll(array1, null)   = cloned copy of array1
    899     * ArrayUtils.addAll(null, array2)   = cloned copy of array2
    900     * ArrayUtils.addAll([], [])         = []
    901     * </pre>
    902     *
    903     * @param array1  the first array whose elements are added to the new array.
    904     * @param array2  the second array whose elements are added to the new array.
    905     * @return The new char[] array.
    906     * @since 2.1
    907     */
    908    public static char[] addAll(final char[] array1, final char... array2) {
    909        if (array1 == null) {
    910            return clone(array2);
    911        }
    912        if (array2 == null) {
    913            return clone(array1);
    914        }
    915        final char[] joinedArray = new char[array1.length + array2.length];
    916        System.arraycopy(array1, 0, joinedArray, 0, array1.length);
    917        System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
    918        return joinedArray;
    919    }
    920
    921    /**
    922     * Adds all the elements of the given arrays into a new array.
    923     * <p>
    924     * The new array contains all of the element of {@code array1} followed
    925     * by all of the elements {@code array2}. When an array is returned, it is always
    926     * a new array.
    927     * </p>
    928     * <pre>
    929     * ArrayUtils.addAll(array1, null)   = cloned copy of array1
    930     * ArrayUtils.addAll(null, array2)   = cloned copy of array2
    931     * ArrayUtils.addAll([], [])         = []
    932     * </pre>
    933     *
    934     * @param array1  the first array whose elements are added to the new array.
    935     * @param array2  the second array whose elements are added to the new array.
    936     * @return The new double[] array.
    937     * @since 2.1
    938     */
    939    public static double[] addAll(final double[] array1, final double... array2) {
    940        if (array1 == null) {
    941            return clone(array2);
    942        }
    943        if (array2 == null) {
    944            return clone(array1);
    945        }
    946        final double[] joinedArray = new double[array1.length + array2.length];
    947        System.arraycopy(array1, 0, joinedArray, 0, array1.length);
    948        System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
    949        return joinedArray;
    950    }
    951
    952    /**
    953     * Adds all the elements of the given arrays into a new array.
    954     * <p>
    955     * The new array contains all of the element of {@code array1} followed
    956     * by all of the elements {@code array2}. When an array is returned, it is always
    957     * a new array.
    958     * </p>
    959     * <pre>
    960     * ArrayUtils.addAll(array1, null)   = cloned copy of array1
    961     * ArrayUtils.addAll(null, array2)   = cloned copy of array2
    962     * ArrayUtils.addAll([], [])         = []
    963     * </pre>
    964     *
    965     * @param array1  the first array whose elements are added to the new array.
    966     * @param array2  the second array whose elements are added to the new array.
    967     * @return The new float[] array.
    968     * @since 2.1
    969     */
    970    public static float[] addAll(final float[] array1, final float... array2) {
    971        if (array1 == null) {
    972            return clone(array2);
    973        }
    974        if (array2 == null) {
    975            return clone(array1);
    976        }
    977        final float[] joinedArray = new float[array1.length + array2.length];
    978        System.arraycopy(array1, 0, joinedArray, 0, array1.length);
    979        System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
    980        return joinedArray;
    981    }
    982
    983    /**
    984     * Adds all the elements of the given arrays into a new array.
    985     * <p>
    986     * The new array contains all of the element of {@code array1} followed
    987     * by all of the elements {@code array2}. When an array is returned, it is always
    988     * a new array.
    989     * </p>
    990     * <pre>
    991     * ArrayUtils.addAll(array1, null)   = cloned copy of array1
    992     * ArrayUtils.addAll(null, array2)   = cloned copy of array2
    993     * ArrayUtils.addAll([], [])         = []
    994     * </pre>
    995     *
    996     * @param array1  the first array whose elements are added to the new array.
    997     * @param array2  the second array whose elements are added to the new array.
    998     * @return The new int[] array.
    999     * @since 2.1
    1000     */
    1001    public static int[] addAll(final int[] array1, final int... array2) {
    1002        if (array1 == null) {
    1003            return clone(array2);
    1004        }
    1005        if (array2 == null) {
    1006            return clone(array1);
    1007        }
    1008        final int[] joinedArray = new int[array1.length + array2.length];
    1009        System.arraycopy(array1, 0, joinedArray, 0, array1.length);
    1010        System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
    1011        return joinedArray;
    1012    }
    1013
    1014    /**
    1015     * Adds all the elements of the given arrays into a new array.
    1016     * <p>
    1017     * The new array contains all of the element of {@code array1} followed
    1018     * by all of the elements {@code array2}. When an array is returned, it is always
    1019     * a new array.
    1020     * </p>
    1021     * <pre>
    1022     * ArrayUtils.addAll(array1, null)   = cloned copy of array1
    1023     * ArrayUtils.addAll(null, array2)   = cloned copy of array2
    1024     * ArrayUtils.addAll([], [])         = []
    1025     * </pre>
    1026     *
    1027     * @param array1  the first array whose elements are added to the new array.
    1028     * @param array2  the second array whose elements are added to the new array.
    1029     * @return The new long[] array.
    1030     * @since 2.1
    1031     */
    1032    public static long[] addAll(final long[] array1, final long... array2) {
    1033        if (array1 == null) {
    1034            return clone(array2);
    1035        }
    1036        if (array2 == null) {
    1037            return clone(array1);
    1038        }
    1039        final long[] joinedArray = new long[array1.length + array2.length];
    1040        System.arraycopy(array1, 0, joinedArray, 0, array1.length);
    1041        System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
    1042        return joinedArray;
    1043    }
    1044
    1045    /**
    1046     * Adds all the elements of the given arrays into a new array.
    1047     * <p>
    1048     * The new array contains all of the element of {@code array1} followed
    1049     * by all of the elements {@code array2}. When an array is returned, it is always
    1050     * a new array.
    1051     * </p>
    1052     * <pre>
    1053     * ArrayUtils.addAll(array1, null)   = cloned copy of array1
    1054     * ArrayUtils.addAll(null, array2)   = cloned copy of array2
    1055     * ArrayUtils.addAll([], [])         = []
    1056     * </pre>
    1057     *
    1058     * @param array1  the first array whose elements are added to the new array.
    1059     * @param array2  the second array whose elements are added to the new array.
    1060     * @return The new short[] array.
    1061     * @since 2.1
    1062     */
    1063    public static short[] addAll(final short[] array1, final short... array2) {
    1064        if (array1 == null) {
    1065            return clone(array2);
    1066        }
    1067        if (array2 == null) {
    1068            return clone(array1);
    1069        }
    1070        final short[] joinedArray = new short[array1.length + array2.length];
    1071        System.arraycopy(array1, 0, joinedArray, 0, array1.length);
    1072        System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
    1073        return joinedArray;
    1074    }
    1075
    1076    /**
    1077     * Adds all the elements of the given arrays into a new array.
    1078     * <p>
    1079     * The new array contains all of the element of {@code array1} followed
    1080     * by all of the elements {@code array2}. When an array is returned, it is always
    1081     * a new array.
    1082     * </p>
    1083     * <pre>
    1084     * ArrayUtils.addAll(null, null)     = null
    1085     * ArrayUtils.addAll(array1, null)   = cloned copy of array1
    1086     * ArrayUtils.addAll(null, array2)   = cloned copy of array2
    1087     * ArrayUtils.addAll([], [])         = []
    1088     * ArrayUtils.addAll([null], [null]) = [null, null]
    1089     * ArrayUtils.addAll(["a", "b", "c"], ["1", "2", "3"]) = ["a", "b", "c", "1", "2", "3"]
    1090     * </pre>
    1091     *
    1092     * @param <T> the component type of the array
    1093     * @param array1  the first array whose elements are added to the new array, may be {@code null}
    1094     * @param array2  the second array whose elements are added to the new array, may be {@code null}
    1095     * @return The new array, {@code null} if both arrays are {@code null}.
    1096     *      The type of the new array is the type of the first array,
    1097     *      unless the first array is null, in which case the type is the same as the second array.
    1098     * @since 2.1
    1099     * @throws IllegalArgumentException if the array types are incompatible
    1100     */
    1101    public static <T> T[] addAll(final T[] array1, @SuppressWarnings("unchecked") final T... array2) {
    1102        if (array1 == null) {
    1103            return clone(array2);
    1104        }
    1105        if (array2 == null) {
    1106            return clone(array1);
    1107        }
    1108        final Class<T> type1 = getComponentType(array1);
    1109        final T[] joinedArray = newInstance(type1, array1.length + array2.length);
    1110        System.arraycopy(array1, 0, joinedArray, 0, array1.length);
    1111        try {
    1112            System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
    1113        } catch (final ArrayStoreException ase) {
    1114            // Check if problem was due to incompatible types
    1115            /*
    1116             * We do this here, rather than before the copy because:
    1117             * - it would be a wasted check most of the time
    1118             * - safer, in case check turns out to be too strict
    1119             */
    1120            final Class<?> type2 = array2.getClass().getComponentType();
    1121            if (!type1.isAssignableFrom(type2)) {
    1122                throw new IllegalArgumentException("Cannot store " + type2.getName() + " in an array of "
    1123                        + type1.getName(), ase);
    1124            }
    1125            throw ase; // No, so rethrow original
    1126        }
    1127        return joinedArray;
    1128    }
    1129
    1130    /**
    1131     * Copies the given array and adds the given element at the beginning of the new array.
    1132     * <p>
    1133     * The new array contains the same elements of the input array plus the given element in the first position. The
    1134     * component type of the new array is the same as that of the input array.
    1135     * </p>
    1136     * <p>
    1137     * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
    1138     * element.
    1139     * </p>
    1140     * <pre>
    1141     * ArrayUtils.addFirst(null, true)          = [true]
    1142     * ArrayUtils.addFirst([true], false)       = [false, true]
    1143     * ArrayUtils.addFirst([true, false], true) = [true, true, false]
    1144     * </pre>
    1145     *
    1146     * @param array the array to "add" the element to, may be {@code null}.
    1147     * @param element the object to add.
    1148     * @return A new array containing the existing elements plus the new element The returned array type will be that of
    1149     *         the input array (unless null), in which case it will have the same type as the element.
    1150     * @since 3.10
    1151     */
    1152    public static boolean[] addFirst(final boolean[] array, final boolean element) {
    1153        return array == null ? add(array, element) : insert(0, array, element);
    1154    }
    1155
    1156    /**
    1157     * Copies the given array and adds the given element at the beginning of the new array.
    1158     * <p>
    1159     * The new array contains the same elements of the input array plus the given element in the first position. The
    1160     * component type of the new array is the same as that of the input array.
    1161     * </p>
    1162     * <p>
    1163     * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
    1164     * element.
    1165     * </p>
    1166     * <pre>
    1167     * ArrayUtils.addFirst(null, 1)   = [1]
    1168     * ArrayUtils.addFirst([1], 0)    = [0, 1]
    1169     * ArrayUtils.addFirst([1, 0], 1) = [1, 1, 0]
    1170     * </pre>
    1171     *
    1172     * @param array the array to "add" the element to, may be {@code null}.
    1173     * @param element the object to add.
    1174     * @return A new array containing the existing elements plus the new element The returned array type will be that of
    1175     *         the input array (unless null), in which case it will have the same type as the element.
    1176     * @since 3.10
    1177     */
    1178    public static byte[] addFirst(final byte[] array, final byte element) {
    1179        return array == null ? add(array, element) : insert(0, array, element);
    1180    }
    1181
    1182    /**
    1183     * Copies the given array and adds the given element at the beginning of the new array.
    1184     * <p>
    1185     * The new array contains the same elements of the input array plus the given element in the first position. The
    1186     * component type of the new array is the same as that of the input array.
    1187     * </p>
    1188     * <p>
    1189     * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
    1190     * element.
    1191     * </p>
    1192     * <pre>
    1193     * ArrayUtils.addFirst(null, '1')       = ['1']
    1194     * ArrayUtils.addFirst(['1'], '0')      = ['0', '1']
    1195     * ArrayUtils.addFirst(['1', '0'], '1') = ['1', '1', '0']
    1196     * </pre>
    1197     *
    1198     * @param array the array to "add" the element to, may be {@code null}.
    1199     * @param element the object to add.
    1200     * @return A new array containing the existing elements plus the new element The returned array type will be that of
    1201     *         the input array (unless null), in which case it will have the same type as the element.
    1202     * @since 3.10
    1203     */
    1204    public static char[] addFirst(final char[] array, final char element) {
    1205        return array == null ? add(array, element) : insert(0, array, element);
    1206    }
    1207
    1208    /**
    1209     * Copies the given array and adds the given element at the beginning of the new array.
    1210     * <p>
    1211     * The new array contains the same elements of the input array plus the given element in the first position. The
    1212     * component type of the new array is the same as that of the input array.
    1213     * </p>
    1214     * <p>
    1215     * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
    1216     * element.
    1217     * </p>
    1218     * <pre>
    1219     * ArrayUtils.addFirst(null, 1)   = [1]
    1220     * ArrayUtils.addFirst([1], 0)    = [0, 1]
    1221     * ArrayUtils.addFirst([1, 0], 1) = [1, 1, 0]
    1222     * </pre>
    1223     *
    1224     * @param array the array to "add" the element to, may be {@code null}.
    1225     * @param element the object to add.
    1226     * @return A new array containing the existing elements plus the new element The returned array type will be that of
    1227     *         the input array (unless null), in which case it will have the same type as the element.
    1228     * @since 3.10
    1229     */
    1230    public static double[] addFirst(final double[] array, final double element) {
    1231        return array == null ? add(array, element) : insert(0, array, element);
    1232    }
    1233
    1234    /**
    1235     * Copies the given array and adds the given element at the beginning of the new array.
    1236     * <p>
    1237     * The new array contains the same elements of the input array plus the given element in the first position. The
    1238     * component type of the new array is the same as that of the input array.
    1239     * </p>
    1240     * <p>
    1241     * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
    1242     * element.
    1243     * </p>
    1244     * <pre>
    1245     * ArrayUtils.addFirst(null, 1)   = [1]
    1246     * ArrayUtils.addFirst([1], 0)    = [0, 1]
    1247     * ArrayUtils.addFirst([1, 0], 1) = [1, 1, 0]
    1248     * </pre>
    1249     *
    1250     * @param array the array to "add" the element to, may be {@code null}.
    1251     * @param element the object to add.
    1252     * @return A new array containing the existing elements plus the new element The returned array type will be that of
    1253     *         the input array (unless null), in which case it will have the same type as the element.
    1254     * @since 3.10
    1255     */
    1256    public static float[] addFirst(final float[] array, final float element) {
    1257        return array == null ? add(array, element) : insert(0, array, element);
    1258    }
    1259
    1260    /**
    1261     * Copies the given array and adds the given element at the beginning of the new array.
    1262     * <p>
    1263     * The new array contains the same elements of the input array plus the given element in the first position. The
    1264     * component type of the new array is the same as that of the input array.
    1265     * </p>
    1266     * <p>
    1267     * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
    1268     * element.
    1269     * </p>
    1270     * <pre>
    1271     * ArrayUtils.addFirst(null, 1)   = [1]
    1272     * ArrayUtils.addFirst([1], 0)    = [0, 1]
    1273     * ArrayUtils.addFirst([1, 0], 1) = [1, 1, 0]
    1274     * </pre>
    1275     *
    1276     * @param array the array to "add" the element to, may be {@code null}.
    1277     * @param element the object to add.
    1278     * @return A new array containing the existing elements plus the new element The returned array type will be that of
    1279     *         the input array (unless null), in which case it will have the same type as the element.
    1280     * @since 3.10
    1281     */
    1282    public static int[] addFirst(final int[] array, final int element) {
    1283        return array == null ? add(array, element) : insert(0, array, element);
    1284    }
    1285
    1286    /**
    1287     * Copies the given array and adds the given element at the beginning of the new array.
    1288     * <p>
    1289     * The new array contains the same elements of the input array plus the given element in the first position. The
    1290     * component type of the new array is the same as that of the input array.
    1291     * </p>
    1292     * <p>
    1293     * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
    1294     * element.
    1295     * </p>
    1296     * <pre>
    1297     * ArrayUtils.addFirst(null, 1)   = [1]
    1298     * ArrayUtils.addFirst([1], 0)    = [0, 1]
    1299     * ArrayUtils.addFirst([1, 0], 1) = [1, 1, 0]
    1300     * </pre>
    1301     *
    1302     * @param array the array to "add" the element to, may be {@code null}.
    1303     * @param element the object to add.
    1304     * @return A new array containing the existing elements plus the new element The returned array type will be that of
    1305     *         the input array (unless null), in which case it will have the same type as the element.
    1306     * @since 3.10
    1307     */
    1308    public static long[] addFirst(final long[] array, final long element) {
    1309        return array == null ? add(array, element) : insert(0, array, element);
    1310    }
    1311
    1312    /**
    1313     * Copies the given array and adds the given element at the beginning of the new array.
    1314     * <p>
    1315     * The new array contains the same elements of the input array plus the given element in the first position. The
    1316     * component type of the new array is the same as that of the input array.
    1317     * </p>
    1318     * <p>
    1319     * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
    1320     * element.
    1321     * </p>
    1322     * <pre>
    1323     * ArrayUtils.addFirst(null, 1)   = [1]
    1324     * ArrayUtils.addFirst([1], 0)    = [0, 1]
    1325     * ArrayUtils.addFirst([1, 0], 1) = [1, 1, 0]
    1326     * </pre>
    1327     *
    1328     * @param array the array to "add" the element to, may be {@code null}.
    1329     * @param element the object to add.
    1330     * @return A new array containing the existing elements plus the new element The returned array type will be that of
    1331     *         the input array (unless null), in which case it will have the same type as the element.
    1332     * @since 3.10
    1333     */
    1334    public static short[] addFirst(final short[] array, final short element) {
    1335        return array == null ? add(array, element) : insert(0, array, element);
    1336    }
    1337
    1338    /**
    1339     * Copies the given array and adds the given element at the beginning of the new array.
    1340     * <p>
    1341     * The new array contains the same elements of the input array plus the given element in the first position. The
    1342     * component type of the new array is the same as that of the input array.
    1343     * </p>
    1344     * <p>
    1345     * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
    1346     * element, unless the element itself is null, in which case the return type is Object[]
    1347     * </p>
    1348     * <pre>
    1349     * ArrayUtils.addFirst(null, null)      = IllegalArgumentException
    1350     * ArrayUtils.addFirst(null, "a")       = ["a"]
    1351     * ArrayUtils.addFirst(["a"], null)     = [null, "a"]
    1352     * ArrayUtils.addFirst(["a"], "b")      = ["b", "a"]
    1353     * ArrayUtils.addFirst(["a", "b"], "c") = ["c", "a", "b"]
    1354     * </pre>
    1355     *
    1356     * @param <T> the component type of the array
    1357     * @param array the array to "add" the element to, may be {@code null}
    1358     * @param element the object to add, may be {@code null}
    1359     * @return A new array containing the existing elements plus the new element The returned array type will be that of
    1360     *         the input array (unless null), in which case it will have the same type as the element. If both are null,
    1361     *         an IllegalArgumentException is thrown
    1362     * @since 3.10
    1363     * @throws IllegalArgumentException if both arguments are null
    1364     */
    1365    public static <T> T[] addFirst(final T[] array, final T element) {
    1366        return array == null ? add(array, element) : insert(0, array, element);
    1367    }
    1368
    1369    /**
    1370     * Clones an array returning a typecast result and handling
    1371     * {@code null}.
    1372     * <p>
    1373     * This method returns {@code null} for a {@code null} input array.
    1374     * </p>
    1375     *
    1376     * @param array  the array to clone, may be {@code null}
    1377     * @return the cloned array, {@code null} if {@code null} input
    1378     */
    1379    public static boolean[] clone(final boolean[] array) {
    1380        return array != null ? array.clone() : null;
    1381    }
    1382
    1383    /**
    1384     * Clones an array returning a typecast result and handling
    1385     * {@code null}.
    1386     * <p>
    1387     * This method returns {@code null} for a {@code null} input array.
    1388     * </p>
    1389     *
    1390     * @param array  the array to clone, may be {@code null}
    1391     * @return the cloned array, {@code null} if {@code null} input
    1392     */
    1393    public static byte[] clone(final byte[] array) {
    1394        return array != null ? array.clone() : null;
    1395    }
    1396
    1397    /**
    1398     * Clones an array returning a typecast result and handling
    1399     * {@code null}.
    1400     * <p>
    1401     * This method returns {@code null} for a {@code null} input array.
    1402     * </p>
    1403     *
    1404     * @param array  the array to clone, may be {@code null}
    1405     * @return the cloned array, {@code null} if {@code null} input
    1406     */
    1407    public static char[] clone(final char[] array) {
    1408        return array != null ? array.clone() : null;
    1409    }
    1410
    1411    /**
    1412     * Clones an array returning a typecast result and handling
    1413     * {@code null}.
    1414     * <p>
    1415     * This method returns {@code null} for a {@code null} input array.
    1416     * </p>
    1417     *
    1418     * @param array  the array to clone, may be {@code null}
    1419     * @return the cloned array, {@code null} if {@code null} input
    1420     */
    1421    public static double[] clone(final double[] array) {
    1422        return array != null ? array.clone() : null;
    1423    }
    1424
    1425    /**
    1426     * Clones an array returning a typecast result and handling
    1427     * {@code null}.
    1428     * <p>
    1429     * This method returns {@code null} for a {@code null} input array.
    1430     * </p>
    1431     *
    1432     * @param array  the array to clone, may be {@code null}
    1433     * @return the cloned array, {@code null} if {@code null} input
    1434     */
    1435    public static float[] clone(final float[] array) {
    1436        return array != null ? array.clone() : null;
    1437    }
    1438
    1439    /**
    1440     * Clones an array returning a typecast result and handling
    1441     * {@code null}.
    1442     * <p>
    1443     * This method returns {@code null} for a {@code null} input array.
    1444     * </p>
    1445     *
    1446     * @param array  the array to clone, may be {@code null}
    1447     * @return the cloned array, {@code null} if {@code null} input
    1448     */
    1449    public static int[] clone(final int[] array) {
    1450        return array != null ? array.clone() : null;
    1451    }
    1452
    1453    /**
    1454     * Clones an array returning a typecast result and handling
    1455     * {@code null}.
    1456     * <p>
    1457     * This method returns {@code null} for a {@code null} input array.
    1458     * </p>
    1459     *
    1460     * @param array  the array to clone, may be {@code null}
    1461     * @return the cloned array, {@code null} if {@code null} input
    1462     */
    1463    public static long[] clone(final long[] array) {
    1464        return array != null ? array.clone() : null;
    1465    }
    1466
    1467    /**
    1468     * Clones an array returning a typecast result and handling
    1469     * {@code null}.
    1470     * <p>
    1471     * This method returns {@code null} for a {@code null} input array.
    1472     * </p>
    1473     *
    1474     * @param array  the array to clone, may be {@code null}
    1475     * @return the cloned array, {@code null} if {@code null} input
    1476     */
    1477    public static short[] clone(final short[] array) {
    1478        return array != null ? array.clone() : null;
    1479    }
    1480
    1481    /**
    1482     * Shallow clones an array returning a typecast result and handling
    1483     * {@code null}.
    1484     * <p>
    1485     * The objects in the array are not cloned, thus there is no special
    1486     * handling for multi-dimensional arrays.
    1487     * </p>
    1488     * <p>
    1489     * This method returns {@code null} for a {@code null} input array.
    1490     * </p>
    1491     *
    1492     * @param <T> the component type of the array
    1493     * @param array  the array to shallow clone, may be {@code null}
    1494     * @return the cloned array, {@code null} if {@code null} input
    1495     */
    1496    public static <T> T[] clone(final T[] array) {
    1497        return array != null ? array.clone() : null;
    1498    }
    1499
    1500    /**
    1501     * Checks if the value is in the given array.
    1502     * <p>
    1503     * The method returns {@code false} if a {@code null} array is passed in.
    1504     * </p>
    1505     *
    1506     * @param array  the array to search through
    1507     * @param valueToFind  the value to find
    1508     * @return {@code true} if the array contains the object
    1509     */
    1510    public static boolean contains(final boolean[] array, final boolean valueToFind) {
    1511        return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
    1512    }
    1513
    1514    /**
    1515     * Checks if the value is in the given array.
    1516     * <p>
    1517     * The method returns {@code false} if a {@code null} array is passed in.
    1518     * </p>
    1519     *
    1520     * @param array  the array to search through
    1521     * @param valueToFind  the value to find
    1522     * @return {@code true} if the array contains the object
    1523     */
    1524    public static boolean contains(final byte[] array, final byte valueToFind) {
    1525        return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
    1526    }
    1527
    1528    /**
    1529     * Checks if the value is in the given array.
    1530     * <p>
    1531     * The method returns {@code false} if a {@code null} array is passed in.
    1532     * </p>
    1533     *
    1534     * @param array  the array to search through
    1535     * @param valueToFind  the value to find
    1536     * @return {@code true} if the array contains the object
    1537     * @since 2.1
    1538     */
    1539    public static boolean contains(final char[] array, final char valueToFind) {
    1540        return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
    1541    }
    1542
    1543    /**
    1544     * Checks if the value is in the given array.
    1545     * <p>
    1546     * The method returns {@code false} if a {@code null} array is passed in.
    1547     * </p>
    1548     *
    1549     * @param array  the array to search through
    1550     * @param valueToFind  the value to find
    1551     * @return {@code true} if the array contains the object
    1552     */
    1553    public static boolean contains(final double[] array, final double valueToFind) {
    1554        return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
    1555    }
    1556
    1557    /**
    1558     * Checks if a value falling within the given tolerance is in the
    1559     * given array.  If the array contains a value within the inclusive range
    1560     * defined by (value - tolerance) to (value + tolerance).
    1561     * <p>
    1562     * The method returns {@code false} if a {@code null} array
    1563     * is passed in.
    1564     * </p>
    1565     *
    1566     * @param array  the array to search
    1567     * @param valueToFind  the value to find
    1568     * @param tolerance  the array contains the tolerance of the search
    1569     * @return true if value falling within tolerance is in array
    1570     */
    1571    public static boolean contains(final double[] array, final double valueToFind, final double tolerance) {
    1572        return indexOf(array, valueToFind, 0, tolerance) != INDEX_NOT_FOUND;
    1573    }
    1574
    1575    /**
    1576     * Checks if the value is in the given array.
    1577     * <p>
    1578     * The method returns {@code false} if a {@code null} array is passed in.
    1579     * </p>
    1580     *
    1581     * @param array  the array to search through
    1582     * @param valueToFind  the value to find
    1583     * @return {@code true} if the array contains the object
    1584     */
    1585    public static boolean contains(final float[] array, final float valueToFind) {
    1586        return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
    1587    }
    1588
    1589    /**
    1590     * Checks if the value is in the given array.
    1591     * <p>
    1592     * The method returns {@code false} if a {@code null} array is passed in.
    1593     * </p>
    1594     *
    1595     * @param array  the array to search through
    1596     * @param valueToFind  the value to find
    1597     * @return {@code true} if the array contains the object
    1598     */
    1599    public static boolean contains(final int[] array, final int valueToFind) {
    1600        return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
    1601    }
    1602
    1603    /**
    1604     * Checks if the value is in the given array.
    1605     * <p>
    1606     * The method returns {@code false} if a {@code null} array is passed in.
    1607     * </p>
    1608     *
    1609     * @param array  the array to search through
    1610     * @param valueToFind  the value to find
    1611     * @return {@code true} if the array contains the object
    1612     */
    1613    public static boolean contains(final long[] array, final long valueToFind) {
    1614        return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
    1615    }
    1616
    1617    /**
    1618     * Checks if the object is in the given array.
    1619     * <p>
    1620     * The method returns {@code false} if a {@code null} array is passed in.
    1621     * </p>
    1622     *
    1623     * @param array  the array to search through
    1624     * @param objectToFind  the object to find
    1625     * @return {@code true} if the array contains the object
    1626     */
    1627    public static boolean contains(final Object[] array, final Object objectToFind) {
    1628        return indexOf(array, objectToFind) != INDEX_NOT_FOUND;
    1629    }
    1630
    1631    /**
    1632     * Checks if the value is in the given array.
    1633     * <p>
    1634     * The method returns {@code false} if a {@code null} array is passed in.
    1635     * </p>
    1636     *
    1637     * @param array  the array to search through
    1638     * @param valueToFind  the value to find
    1639     * @return {@code true} if the array contains the object
    1640     */
    1641    public static boolean contains(final short[] array, final short valueToFind) {
    1642        return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
    1643    }
    1644
    1645    /**
    1646     * Checks if any of the objects are in the given array.
    1647     * <p>
    1648     * The method returns {@code false} if a {@code null} array is passed in.
    1649     * </p>
    1650     *
    1651     * @param array  the array to search through
    1652     * @param objectsToFind  any of the objects to find
    1653     * @return {@code true} if the array contains any of the objects
    1654     * @since 3.13.0
    1655     */
    1656    public static boolean containsAny(final Object[] array, final Object... objectsToFind) {
    1657        return Streams.of(objectsToFind).anyMatch(e -> contains(array, e));
    1658    }
    1659
    1660    /**
    1661     * Returns a copy of the given array of size 1 greater than the argument.
    1662     * The last value of the array is left to the default value.
    1663     *
    1664     * @param array The array to copy, must not be {@code null}.
    1665     * @param newArrayComponentType If {@code array} is {@code null}, create a
    1666     * size 1 array of this type.
    1667     * @return A new copy of the array of size 1 greater than the input.
    1668     */
    1669    private static Object copyArrayGrow1(final Object array, final Class<?> newArrayComponentType) {
    1670        if (array != null) {
    1671            final int arrayLength = Array.getLength(array);
    1672            final Object newArray = Array.newInstance(array.getClass().getComponentType(), arrayLength + 1);
    1673            System.arraycopy(array, 0, newArray, 0, arrayLength);
    1674            return newArray;
    1675        }
    1676        return Array.newInstance(newArrayComponentType, 1);
    1677    }
    1678
    1679    /**
    1680     * Gets the nTh element of an array or null if the index is out of bounds or the array is null.
    1681     *
    1682     * @param <T> The type of array elements.
    1683     * @param array The array to index.
    1684     * @param index The index
    1685     * @return the nTh element of an array or null if the index is out of bounds or the array is null.
    1686     * @since 3.11
    1687     */
    1688    public static <T> T get(final T[] array, final int index) {
    1689        return get(array, index, null);
    1690    }
    1691
    1692    /**
    1693     * Gets the nTh element of an array or a default value if the index is out of bounds.
    1694     *
    1695     * @param <T> The type of array elements.
    1696     * @param array The array to index.
    1697     * @param index The index
    1698     * @param defaultValue The return value of the given index is out of bounds.
    1699     * @return the nTh element of an array or a default value if the index is out of bounds.
    1700     * @since 3.11
    1701     */
    1702    public static <T> T get(final T[] array, final int index, final T defaultValue) {
    1703        return isArrayIndexValid(array, index) ? array[index] : defaultValue;
    1704    }
    1705
    1706    /**
    1707     * Gets an array's component type.
    1708     *
    1709     * @param <T> The array type.
    1710     * @param array The array.
    1711     * @return The component type.
    1712     * @since 3.13.0
    1713     */
    1714    public static <T> Class<T> getComponentType(final T[] array) {
    1715        return ClassUtils.getComponentType(ObjectUtils.getClass(array));
    1716    }
    1717
    1718    /**
    1719     * Returns the length of the specified array.
    1720     * This method can deal with {@link Object} arrays and with primitive arrays.
    1721     * <p>
    1722     * If the input array is {@code null}, {@code 0} is returned.
    1723     * </p>
    1724     * <pre>
    1725     * ArrayUtils.getLength(null)            = 0
    1726     * ArrayUtils.getLength([])              = 0
    1727     * ArrayUtils.getLength([null])          = 1
    1728     * ArrayUtils.getLength([true, false])   = 2
    1729     * ArrayUtils.getLength([1, 2, 3])       = 3
    1730     * ArrayUtils.getLength(["a", "b", "c"]) = 3
    1731     * </pre>
    1732     *
    1733     * @param array  the array to retrieve the length from, may be null
    1734     * @return The length of the array, or {@code 0} if the array is {@code null}
    1735     * @throws IllegalArgumentException if the object argument is not an array.
    1736     * @since 2.1
    1737     */
    1738    public static int getLength(final Object array) {
    1739        return array != null ? Array.getLength(array) : 0;
    1740    }
    1741
    1742    /**
    1743     * Get a hash code for an array handling multidimensional arrays correctly.
    1744     * <p>
    1745     * Multi-dimensional primitive arrays are also handled correctly by this method.
    1746     * </p>
    1747     *
    1748     * @param array  the array to get a hash code for, {@code null} returns zero
    1749     * @return a hash code for the array
    1750     */
    1751    public static int hashCode(final Object array) {
    1752        return new HashCodeBuilder().append(array).toHashCode();
    1753    }
    1754
    1755    /**
    1756     * Finds the indices of the given value in the array.
    1757     * <p>
    1758     * This method returns an empty BitSet for a {@code null} input array.
    1759     * </p>
    1760     *
    1761     * @param array  the array to search through for the object, may be {@code null}
    1762     * @param valueToFind  the value to find
    1763     * @return a BitSet of all the indices of the value within the array,
    1764     *  an empty BitSet if not found or {@code null} array input
    1765     * @since 3.10
    1766     */
    1767    public static BitSet indexesOf(final boolean[] array, final boolean valueToFind) {
    1768        return indexesOf(array, valueToFind, 0);
    1769    }
    1770
    1771    /**
    1772     * Finds the indices of the given value in the array starting at the given index.
    1773     * <p>
    1774     * This method returns an empty BitSet for a {@code null} input array.
    1775     * </p>
    1776     * <p>
    1777     * A negative startIndex is treated as zero. A startIndex larger than the array
    1778     * length will return an empty BitSet ({@code -1}).
    1779     * </p>
    1780     *
    1781     * @param array  the array to search through for the object, may be {@code null}
    1782     * @param valueToFind  the value to find
    1783     * @param startIndex  the index to start searching at
    1784     * @return a BitSet of all the indices of the value within the array,
    1785     *  an empty BitSet if not found or {@code null}
    1786     *  array input
    1787     * @since 3.10
    1788     */
    1789    public static BitSet indexesOf(final boolean[] array, final boolean valueToFind, int startIndex) {
    1790        final BitSet bitSet = new BitSet();
    1791
    1792        if (array == null) {
    1793            return bitSet;
    1794        }
    1795
    1796        while (startIndex < array.length) {
    1797            startIndex = indexOf(array, valueToFind, startIndex);
    1798
    1799            if (startIndex == INDEX_NOT_FOUND) {
    1800                break;
    1801            }
    1802
    1803            bitSet.set(startIndex);
    1804            ++startIndex;
    1805        }
    1806
    1807        return bitSet;
    1808    }
    1809
    1810    /**
    1811     * Finds the indices of the given value in the array.
    1812     *
    1813     * <p>This method returns an empty BitSet for a {@code null} input array.</p>
    1814     *
    1815     * @param array  the array to search through for the object, may be {@code null}
    1816     * @param valueToFind  the value to find
    1817     * @return a BitSet of all the indices of the value within the array,
    1818     *  an empty BitSet if not found or {@code null} array input
    1819     * @since 3.10
    1820     */
    1821    public static BitSet indexesOf(final byte[] array, final byte valueToFind) {
    1822        return indexesOf(array, valueToFind, 0);
    1823    }
    1824
    1825    /**
    1826     * Finds the indices of the given value in the array starting at the given index.
    1827     *
    1828     * <p>This method returns an empty BitSet for a {@code null} input array.</p>
    1829     *
    1830     * <p>A negative startIndex is treated as zero. A startIndex larger than the array
    1831     * length will return an empty BitSet.</p>
    1832     *
    1833     * @param array  the array to search through for the object, may be {@code null}
    1834     * @param valueToFind  the value to find
    1835     * @param startIndex  the index to start searching at
    1836     * @return a BitSet of all the indices of the value within the array,
    1837     *  an empty BitSet if not found or {@code null} array input
    1838     * @since 3.10
    1839     */
    1840    public static BitSet indexesOf(final byte[] array, final byte valueToFind, int startIndex) {
    1841        final BitSet bitSet = new BitSet();
    1842
    1843        if (array == null) {
    1844            return bitSet;
    1845        }
    1846
    1847        while (startIndex < array.length) {
    1848            startIndex = indexOf(array, valueToFind, startIndex);
    1849
    1850            if (startIndex == INDEX_NOT_FOUND) {
    1851                break;
    1852            }
    1853
    1854            bitSet.set(startIndex);
    1855            ++startIndex;
    1856        }
    1857
    1858        return bitSet;
    1859    }
    1860
    1861    /**
    1862     * Finds the indices of the given value in the array.
    1863     *
    1864     * <p>This method returns an empty BitSet for a {@code null} input array.</p>
    1865     *
    1866     * @param array  the array to search through for the object, may be {@code null}
    1867     * @param valueToFind  the value to find
    1868     * @return a BitSet of all the indices of the value within the array,
    1869     *  an empty BitSet if not found or {@code null} array input
    1870     * @since 3.10
    1871     */
    1872    public static BitSet indexesOf(final char[] array, final char valueToFind) {
    1873        return indexesOf(array, valueToFind, 0);
    1874    }
    1875
    1876    /**
    1877     * Finds the indices of the given value in the array starting at the given index.
    1878     *
    1879     * <p>This method returns an empty BitSet for a {@code null} input array.</p>
    1880     *
    1881     * <p>A negative startIndex is treated as zero. A startIndex larger than the array
    1882     * length will return an empty BitSet.</p>
    1883     *
    1884     * @param array  the array to search through for the object, may be {@code null}
    1885     * @param valueToFind  the value to find
    1886     * @param startIndex  the index to start searching at
    1887     * @return a BitSet of all the indices of the value within the array,
    1888     *  an empty BitSet if not found or {@code null} array input
    1889     * @since 3.10
    1890     */
    1891    public static BitSet indexesOf(final char[] array, final char valueToFind, int startIndex) {
    1892        final BitSet bitSet = new BitSet();
    1893
    1894        if (array == null) {
    1895            return bitSet;
    1896        }
    1897
    1898        while (startIndex < array.length) {
    1899            startIndex = indexOf(array, valueToFind, startIndex);
    1900
    1901            if (startIndex == INDEX_NOT_FOUND) {
    1902                break;
    1903            }
    1904
    1905            bitSet.set(startIndex);
    1906            ++startIndex;
    1907        }
    1908
    1909        return bitSet;
    1910    }
    1911
    1912    /**
    1913     * Finds the indices of the given value in the array.
    1914     *
    1915     * <p>This method returns empty BitSet for a {@code null} input array.</p>
    1916     *
    1917     * @param array  the array to search through for the object, may be {@code null}
    1918     * @param valueToFind  the value to find
    1919     * @return a BitSet of all the indices of the value within the array,
    1920     *  an empty BitSet if not found or {@code null} array input
    1921     * @since 3.10
    1922     */
    1923    public static BitSet indexesOf(final double[] array, final double valueToFind) {
    1924        return indexesOf(array, valueToFind, 0);
    1925    }
    1926
    1927    /**
    1928     * Finds the indices of the given value within a given tolerance in the array.
    1929     *
    1930     * <p>
    1931     * This method will return all the indices of the value which fall between the region
    1932     * defined by valueToFind - tolerance and valueToFind + tolerance, each time between the nearest integers.
    1933     * </p>
    1934     *
    1935     * <p>This method returns an empty BitSet for a {@code null} input array.</p>
    1936     *
    1937     * @param array  the array to search through for the object, may be {@code null}
    1938     * @param valueToFind  the value to find
    1939     * @param tolerance tolerance of the search
    1940     * @return a BitSet of all the indices of the value within the array,
    1941     *  an empty BitSet if not found or {@code null} array input
    1942     * @since 3.10
    1943     */
    1944    public static BitSet indexesOf(final double[] array, final double valueToFind, final double tolerance) {
    1945        return indexesOf(array, valueToFind, 0, tolerance);
    1946    }
    1947
    1948    /**
    1949     * Finds the indices of the given value in the array starting at the given index.
    1950     *
    1951     * <p>This method returns an empty BitSet for a {@code null} input array.</p>
    1952     *
    1953     * <p>A negative startIndex is treated as zero. A startIndex larger than the array
    1954     * length will return an empty BitSet.</p>
    1955     *
    1956     * @param array  the array to search through for the object, may be {@code null}
    1957     * @param valueToFind  the value to find
    1958     * @param startIndex  the index to start searching at
    1959     * @return a BitSet of the indices of the value within the array,
    1960     *  an empty BitSet if not found or {@code null} array input
    1961     * @since 3.10
    1962     */
    1963    public static BitSet indexesOf(final double[] array, final double valueToFind, int startIndex) {
    1964        final BitSet bitSet = new BitSet();
    1965
    1966        if (array == null) {
    1967            return bitSet;
    1968        }
    1969
    1970        while (startIndex < array.length) {
    1971            startIndex = indexOf(array, valueToFind, startIndex);
    1972
    1973            if (startIndex == INDEX_NOT_FOUND) {
    1974                break;
    1975            }
    1976
    1977            bitSet.set(startIndex);
    1978            ++startIndex;
    1979        }
    1980
    1981        return bitSet;
    1982    }
    1983
    1984    /**
    1985     * Finds the indices of the given value in the array starting at the given index.
    1986     *
    1987     * <p>
    1988     * This method will return the indices of the values which fall between the region
    1989     * defined by valueToFind - tolerance and valueToFind + tolerance, between the nearest integers.
    1990     * </p>
    1991     *
    1992     * <p>This method returns an empty BitSet for a {@code null} input array.</p>
    1993     *
    1994     * <p>A negative startIndex is treated as zero. A startIndex larger than the array
    1995     * length will return an empty BitSet.</p>
    1996     *
    1997     * @param array  the array to search through for the object, may be {@code null}
    1998     * @param valueToFind  the value to find
    1999     * @param startIndex  the index to start searching at
    2000     * @param tolerance tolerance of the search
    2001     * @return a BitSet of the indices of the value within the array,
    2002     *  an empty BitSet if not found or {@code null} array input
    2003     * @since 3.10
    2004     */
    2005    public static BitSet indexesOf(final double[] array, final double valueToFind, int startIndex, final double tolerance) {
    2006        final BitSet bitSet = new BitSet();
    2007
    2008        if (array == null) {
    2009            return bitSet;
    2010        }
    2011
    2012        while (startIndex < array.length) {
    2013            startIndex = indexOf(array, valueToFind, startIndex, tolerance);
    2014
    2015            if (startIndex == INDEX_NOT_FOUND) {
    2016                break;
    2017            }
    2018
    2019            bitSet.set(startIndex);
    2020            ++startIndex;
    2021        }
    2022
    2023        return bitSet;
    2024    }
    2025
    2026    /**
    2027     * Finds the indices of the given value in the array.
    2028     *
    2029     * <p>This method returns an empty BitSet for a {@code null} input array.</p>
    2030     *
    2031     * @param array  the array to search through for the object, may be {@code null}
    2032     * @param valueToFind  the value to find
    2033     * @return a BitSet of all the indices of the value within the array,
    2034     *  an empty BitSet if not found or {@code null} array input
    2035     * @since 3.10
    2036     */
    2037    public static BitSet indexesOf(final float[] array, final float valueToFind) {
    2038        return indexesOf(array, valueToFind, 0);
    2039    }
    2040
    2041    /**
    2042     * Finds the indices of the given value in the array starting at the given index.
    2043     *
    2044     * <p>This method returns an empty BitSet for a {@code null} input array.</p>
    2045     *
    2046     * <p>A negative startIndex is treated as zero. A startIndex larger than the array
    2047     * length will return empty BitSet.</p>
    2048     *
    2049     * @param array  the array to search through for the object, may be {@code null}
    2050     * @param valueToFind  the value to find
    2051     * @param startIndex  the index to start searching at
    2052     * @return a BitSet of all the indices of the value within the array,
    2053     *  an empty BitSet if not found or {@code null} array input
    2054     * @since 3.10
    2055     */
    2056    public static BitSet indexesOf(final float[] array, final float valueToFind, int startIndex) {
    2057        final BitSet bitSet = new BitSet();
    2058
    2059        if (array == null) {
    2060            return bitSet;
    2061        }
    2062
    2063        while (startIndex < array.length) {
    2064            startIndex = indexOf(array, valueToFind, startIndex);
    2065
    2066            if (startIndex == INDEX_NOT_FOUND) {
    2067                break;
    2068            }
    2069
    2070            bitSet.set(startIndex);
    2071            ++startIndex;
    2072        }
    2073
    2074        return bitSet;
    2075    }
    2076
    2077    /**
    2078     * Finds the indices of the given value in the array.
    2079     *
    2080     * <p>This method returns an empty BitSet for a {@code null} input array.</p>
    2081     *
    2082     * @param array  the array to search through for the object, may be {@code null}
    2083     * @param valueToFind  the value to find
    2084     * @return a BitSet of all the indices of the value within the array,
    2085     *  an empty BitSet if not found or {@code null} array input
    2086     * @since 3.10
    2087     */
    2088    public static BitSet indexesOf(final int[] array, final int valueToFind) {
    2089        return indexesOf(array, valueToFind, 0);
    2090    }
    2091
    2092    /**
    2093     * Finds the indices of the given value in the array starting at the given index.
    2094     *
    2095     * <p>This method returns an empty BitSet for a {@code null} input array.</p>
    2096     *
    2097     * <p>A negative startIndex is treated as zero. A startIndex larger than the array
    2098     * length will return an empty BitSet.</p>
    2099     *
    2100     * @param array  the array to search through for the object, may be {@code null}
    2101     * @param valueToFind  the value to find
    2102     * @param startIndex  the index to start searching at
    2103     * @return a BitSet of all the indices of the value within the array,
    2104     *  an empty BitSet if not found or {@code null} array input
    2105     * @since 3.10
    2106     */
    2107    public static BitSet indexesOf(final int[] array, final int valueToFind, int startIndex) {
    2108        final BitSet bitSet = new BitSet();
    2109
    2110        if (array == null) {
    2111            return bitSet;
    2112        }
    2113
    2114        while (startIndex < array.length) {
    2115            startIndex = indexOf(array, valueToFind, startIndex);
    2116
    2117            if (startIndex == INDEX_NOT_FOUND) {
    2118                break;
    2119            }
    2120
    2121            bitSet.set(startIndex);
    2122            ++startIndex;
    2123        }
    2124
    2125        return bitSet;
    2126    }
    2127
    2128    /**
    2129     * Finds the indices of the given value in the array.
    2130     *
    2131     * <p>This method returns an empty BitSet for a {@code null} input array.</p>
    2132     *
    2133     * @param array  the array to search through for the object, may be {@code null}
    2134     * @param valueToFind  the value to find
    2135     * @return a BitSet of all the indices of the value within the array,
    2136     *  an empty BitSet if not found or {@code null} array input
    2137     * @since 3.10
    2138     */
    2139    public static BitSet indexesOf(final long[] array, final long valueToFind) {
    2140        return indexesOf(array, valueToFind, 0);
    2141    }
    2142
    2143    /**
    2144     * Finds the indices of the given value in the array starting at the given index.
    2145     *
    2146     * <p>This method returns an empty BitSet for a {@code null} input array.</p>
    2147     *
    2148     * <p>A negative startIndex is treated as zero. A startIndex larger than the array
    2149     * length will return an empty BitSet.</p>
    2150     *
    2151     * @param array  the array to search through for the object, may be {@code null}
    2152     * @param valueToFind  the value to find
    2153     * @param startIndex  the index to start searching at
    2154     * @return a BitSet of all the indices of the value within the array,
    2155     *  an empty BitSet if not found or {@code null} array input
    2156     * @since 3.10
    2157     */
    2158    public static BitSet indexesOf(final long[] array, final long valueToFind, int startIndex) {
    2159        final BitSet bitSet = new BitSet();
    2160
    2161        if (array == null) {
    2162            return bitSet;
    2163        }
    2164
    2165        while (startIndex < array.length) {
    2166            startIndex = indexOf(array, valueToFind, startIndex);
    2167
    2168            if (startIndex == INDEX_NOT_FOUND) {
    2169                break;
    2170            }
    2171
    2172            bitSet.set(startIndex);
    2173            ++startIndex;
    2174        }
    2175
    2176        return bitSet;
    2177    }
    2178
    2179    /**
    2180     * Finds the indices of the given object in the array.
    2181     *
    2182     * <p>This method returns an empty BitSet for a {@code null} input array.</p>
    2183     *
    2184     * @param array  the array to search through for the object, may be {@code null}
    2185     * @param objectToFind  the object to find, may be {@code null}
    2186     * @return a BitSet of all the indices of the object within the array,
    2187     *  an empty BitSet if not found or {@code null} array input
    2188     * @since 3.10
    2189     */
    2190    public static BitSet indexesOf(final Object[] array, final Object objectToFind) {
    2191        return indexesOf(array, objectToFind, 0);
    2192    }
    2193
    2194    /**
    2195     * Finds the indices of the given object in the array starting at the given index.
    2196     *
    2197     * <p>This method returns an empty BitSet for a {@code null} input array.</p>
    2198     *
    2199     * <p>A negative startIndex is treated as zero. A startIndex larger than the array
    2200     * length will return an empty BitSet.</p>
    2201     *
    2202     * @param array  the array to search through for the object, may be {@code null}
    2203     * @param objectToFind  the object to find, may be {@code null}
    2204     * @param startIndex  the index to start searching at
    2205     * @return a BitSet of all the indices of the object within the array starting at the index,
    2206     *  an empty BitSet if not found or {@code null} array input
    2207     * @since 3.10
    2208     */
    2209    public static BitSet indexesOf(final Object[] array, final Object objectToFind, int startIndex) {
    2210        final BitSet bitSet = new BitSet();
    2211
    2212        if (array == null) {
    2213            return bitSet;
    2214        }
    2215
    2216        while (startIndex < array.length) {
    2217            startIndex = indexOf(array, objectToFind, startIndex);
    2218
    2219            if (startIndex == INDEX_NOT_FOUND) {
    2220                break;
    2221            }
    2222
    2223            bitSet.set(startIndex);
    2224            ++startIndex;
    2225        }
    2226
    2227        return bitSet;
    2228    }
    2229
    2230    /**
    2231     * Finds the indices of the given value in the array.
    2232     *
    2233     * <p>This method returns an empty BitSet for a {@code null} input array.</p>
    2234     *
    2235     * @param array  the array to search through for the object, may be {@code null}
    2236     * @param valueToFind  the value to find
    2237     * @return a BitSet of all the indices of the value within the array,
    2238     *  an empty BitSet if not found or {@code null} array input
    2239     * @since 3.10
    2240     */
    2241    public static BitSet indexesOf(final short[] array, final short valueToFind) {
    2242        return indexesOf(array, valueToFind, 0);
    2243    }
    2244
    2245    /**
    2246     * Finds the indices of the given value in the array starting at the given index.
    2247     *
    2248     * <p>This method returns an empty BitSet for a {@code null} input array.</p>
    2249     *
    2250     * <p>A negative startIndex is treated as zero. A startIndex larger than the array
    2251     * length will return an empty BitSet.</p>
    2252     *
    2253     * @param array  the array to search through for the object, may be {@code null}
    2254     * @param valueToFind  the value to find
    2255     * @param startIndex  the index to start searching at
    2256     * @return a BitSet of all the indices of the value within the array,
    2257     *  an empty BitSet if not found or {@code null} array input
    2258     * @since 3.10
    2259     */
    2260    public static BitSet indexesOf(final short[] array, final short valueToFind, int startIndex) {
    2261        final BitSet bitSet = new BitSet();
    2262
    2263        if (array == null) {
    2264            return bitSet;
    2265        }
    2266
    2267        while (startIndex < array.length) {
    2268            startIndex = indexOf(array, valueToFind, startIndex);
    2269
    2270            if (startIndex == INDEX_NOT_FOUND) {
    2271                break;
    2272            }
    2273
    2274            bitSet.set(startIndex);
    2275            ++startIndex;
    2276        }
    2277
    2278        return bitSet;
    2279    }
    2280
    2281    /**
    2282     * Finds the index of the given value in the array.
    2283     * <p>
    2284     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    2285     * </p>
    2286     *
    2287     * @param array  the array to search through for the object, may be {@code null}
    2288     * @param valueToFind  the value to find
    2289     * @return the index of the value within the array,
    2290     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    2291     */
    2292    public static int indexOf(final boolean[] array, final boolean valueToFind) {
    2293        return indexOf(array, valueToFind, 0);
    2294    }
    2295
    2296    /**
    2297     * Finds the index of the given value in the array starting at the given index.
    2298     * <p>
    2299     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    2300     * </p>
    2301     * <p>
    2302     * A negative startIndex is treated as zero. A startIndex larger than the array
    2303     * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
    2304     * </p>
    2305     *
    2306     * @param array  the array to search through for the object, may be {@code null}
    2307     * @param valueToFind  the value to find
    2308     * @param startIndex  the index to start searching at
    2309     * @return the index of the value within the array,
    2310     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null}
    2311     *  array input
    2312     */
    2313    public static int indexOf(final boolean[] array, final boolean valueToFind, int startIndex) {
    2314        if (isEmpty(array)) {
    2315            return INDEX_NOT_FOUND;
    2316        }
    2317        if (startIndex < 0) {
    2318            startIndex = 0;
    2319        }
    2320        for (int i = startIndex; i < array.length; i++) {
    2321            if (valueToFind == array[i]) {
    2322                return i;
    2323            }
    2324        }
    2325        return INDEX_NOT_FOUND;
    2326    }
    2327
    2328    /**
    2329     * Finds the index of the given value in the array.
    2330     * <p>
    2331     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    2332     * </p>
    2333     *
    2334     * @param array  the array to search through for the object, may be {@code null}
    2335     * @param valueToFind  the value to find
    2336     * @return the index of the value within the array,
    2337     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    2338     */
    2339    public static int indexOf(final byte[] array, final byte valueToFind) {
    2340        return indexOf(array, valueToFind, 0);
    2341    }
    2342
    2343    /**
    2344     * Finds the index of the given value in the array starting at the given index.
    2345     * <p>
    2346     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    2347     * </p>
    2348     * <p>
    2349     * A negative startIndex is treated as zero. A startIndex larger than the array
    2350     * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
    2351     * </p>
    2352     *
    2353     * @param array  the array to search through for the object, may be {@code null}
    2354     * @param valueToFind  the value to find
    2355     * @param startIndex  the index to start searching at
    2356     * @return the index of the value within the array,
    2357     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    2358     */
    2359    public static int indexOf(final byte[] array, final byte valueToFind, int startIndex) {
    2360        if (array == null) {
    2361            return INDEX_NOT_FOUND;
    2362        }
    2363        if (startIndex < 0) {
    2364            startIndex = 0;
    2365        }
    2366        for (int i = startIndex; i < array.length; i++) {
    2367            if (valueToFind == array[i]) {
    2368                return i;
    2369            }
    2370        }
    2371        return INDEX_NOT_FOUND;
    2372    }
    2373
    2374    /**
    2375     * Finds the index of the given value in the array.
    2376     * <p>
    2377     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    2378     * </p>
    2379     *
    2380     * @param array  the array to search through for the object, may be {@code null}
    2381     * @param valueToFind  the value to find
    2382     * @return the index of the value within the array,
    2383     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    2384     * @since 2.1
    2385     */
    2386    public static int indexOf(final char[] array, final char valueToFind) {
    2387        return indexOf(array, valueToFind, 0);
    2388    }
    2389
    2390    /**
    2391     * Finds the index of the given value in the array starting at the given index.
    2392     * <p>
    2393     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    2394     * </p>
    2395     * <p>
    2396     * A negative startIndex is treated as zero. A startIndex larger than the array
    2397     * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
    2398     * </p>
    2399     *
    2400     * @param array  the array to search through for the object, may be {@code null}
    2401     * @param valueToFind  the value to find
    2402     * @param startIndex  the index to start searching at
    2403     * @return the index of the value within the array,
    2404     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    2405     * @since 2.1
    2406     */
    2407    public static int indexOf(final char[] array, final char valueToFind, int startIndex) {
    2408        if (array == null) {
    2409            return INDEX_NOT_FOUND;
    2410        }
    2411        if (startIndex < 0) {
    2412            startIndex = 0;
    2413        }
    2414        for (int i = startIndex; i < array.length; i++) {
    2415            if (valueToFind == array[i]) {
    2416                return i;
    2417            }
    2418        }
    2419        return INDEX_NOT_FOUND;
    2420    }
    2421
    2422    /**
    2423     * Finds the index of the given value in the array.
    2424     * <p>
    2425     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    2426     * </p>
    2427     *
    2428     * @param array  the array to search through for the object, may be {@code null}
    2429     * @param valueToFind  the value to find
    2430     * @return the index of the value within the array,
    2431     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    2432     */
    2433    public static int indexOf(final double[] array, final double valueToFind) {
    2434        return indexOf(array, valueToFind, 0);
    2435    }
    2436
    2437    /**
    2438     * Finds the index of the given value within a given tolerance in the array.
    2439     * This method will return the index of the first value which falls between the region
    2440     * defined by valueToFind - tolerance and valueToFind + tolerance.
    2441     * <p>
    2442     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    2443     * </p>
    2444     *
    2445     * @param array  the array to search through for the object, may be {@code null}
    2446     * @param valueToFind  the value to find
    2447     * @param tolerance tolerance of the search
    2448     * @return the index of the value within the array,
    2449     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    2450     */
    2451    public static int indexOf(final double[] array, final double valueToFind, final double tolerance) {
    2452        return indexOf(array, valueToFind, 0, tolerance);
    2453    }
    2454
    2455    /**
    2456     * Finds the index of the given value in the array starting at the given index.
    2457     * <p>
    2458     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    2459     * </p>
    2460     * <p>
    2461     * A negative startIndex is treated as zero. A startIndex larger than the array
    2462     * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
    2463     * </p>
    2464     *
    2465     * @param array  the array to search through for the object, may be {@code null}
    2466     * @param valueToFind  the value to find
    2467     * @param startIndex  the index to start searching at
    2468     * @return the index of the value within the array,
    2469     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    2470     */
    2471    public static int indexOf(final double[] array, final double valueToFind, int startIndex) {
    2472        if (isEmpty(array)) {
    2473            return INDEX_NOT_FOUND;
    2474        }
    2475        if (startIndex < 0) {
    2476            startIndex = 0;
    2477        }
    2478        final boolean searchNaN = Double.isNaN(valueToFind);
    2479        for (int i = startIndex; i < array.length; i++) {
    2480            final double element = array[i];
    2481            if (valueToFind == element || searchNaN && Double.isNaN(element)) {
    2482                return i;
    2483            }
    2484        }
    2485        return INDEX_NOT_FOUND;
    2486    }
    2487
    2488    /**
    2489     * Finds the index of the given value in the array starting at the given index.
    2490     * This method will return the index of the first value which falls between the region
    2491     * defined by valueToFind - tolerance and valueToFind + tolerance.
    2492     * <p>
    2493     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    2494     * </p>
    2495     * <p>
    2496     * A negative startIndex is treated as zero. A startIndex larger than the array
    2497     * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
    2498     * </p>
    2499     *
    2500     * @param array  the array to search through for the object, may be {@code null}
    2501     * @param valueToFind  the value to find
    2502     * @param startIndex  the index to start searching at
    2503     * @param tolerance tolerance of the search
    2504     * @return the index of the value within the array,
    2505     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    2506     */
    2507    public static int indexOf(final double[] array, final double valueToFind, int startIndex, final double tolerance) {
    2508        if (isEmpty(array)) {
    2509            return INDEX_NOT_FOUND;
    2510        }
    2511        if (startIndex < 0) {
    2512            startIndex = 0;
    2513        }
    2514        final double min = valueToFind - tolerance;
    2515        final double max = valueToFind + tolerance;
    2516        for (int i = startIndex; i < array.length; i++) {
    2517            if (array[i] >= min && array[i] <= max) {
    2518                return i;
    2519            }
    2520        }
    2521        return INDEX_NOT_FOUND;
    2522    }
    2523
    2524    /**
    2525     * Finds the index of the given value in the array.
    2526     * <p>
    2527     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    2528     * </p>
    2529     *
    2530     * @param array  the array to search through for the object, may be {@code null}
    2531     * @param valueToFind  the value to find
    2532     * @return the index of the value within the array,
    2533     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    2534     */
    2535    public static int indexOf(final float[] array, final float valueToFind) {
    2536        return indexOf(array, valueToFind, 0);
    2537    }
    2538
    2539    /**
    2540     * Finds the index of the given value in the array starting at the given index.
    2541     * <p>
    2542     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    2543     * </p>
    2544     * <p>
    2545     * A negative startIndex is treated as zero. A startIndex larger than the array
    2546     * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
    2547     * </p>
    2548     *
    2549     * @param array  the array to search through for the object, may be {@code null}
    2550     * @param valueToFind  the value to find
    2551     * @param startIndex  the index to start searching at
    2552     * @return the index of the value within the array,
    2553     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    2554     */
    2555    public static int indexOf(final float[] array, final float valueToFind, int startIndex) {
    2556        if (isEmpty(array)) {
    2557            return INDEX_NOT_FOUND;
    2558        }
    2559        if (startIndex < 0) {
    2560            startIndex = 0;
    2561        }
    2562        final boolean searchNaN = Float.isNaN(valueToFind);
    2563        for (int i = startIndex; i < array.length; i++) {
    2564            final float element = array[i];
    2565            if (valueToFind == element || searchNaN && Float.isNaN(element)) {
    2566                return i;
    2567            }
    2568        }
    2569        return INDEX_NOT_FOUND;
    2570    }
    2571
    2572    /**
    2573     * Finds the index of the given value in the array.
    2574     * <p>
    2575     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    2576     * </p>
    2577     *
    2578     * @param array  the array to search through for the object, may be {@code null}
    2579     * @param valueToFind  the value to find
    2580     * @return the index of the value within the array,
    2581     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    2582     */
    2583    public static int indexOf(final int[] array, final int valueToFind) {
    2584        return indexOf(array, valueToFind, 0);
    2585    }
    2586
    2587    /**
    2588     * Finds the index of the given value in the array starting at the given index.
    2589     * <p>
    2590     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    2591     * </p>
    2592     * <p>
    2593     * A negative startIndex is treated as zero. A startIndex larger than the array
    2594     * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
    2595     * </p>
    2596     *
    2597     * @param array  the array to search through for the object, may be {@code null}
    2598     * @param valueToFind  the value to find
    2599     * @param startIndex  the index to start searching at
    2600     * @return the index of the value within the array,
    2601     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    2602     */
    2603    public static int indexOf(final int[] array, final int valueToFind, int startIndex) {
    2604        if (array == null) {
    2605            return INDEX_NOT_FOUND;
    2606        }
    2607        if (startIndex < 0) {
    2608            startIndex = 0;
    2609        }
    2610        for (int i = startIndex; i < array.length; i++) {
    2611            if (valueToFind == array[i]) {
    2612                return i;
    2613            }
    2614        }
    2615        return INDEX_NOT_FOUND;
    2616    }
    2617
    2618    /**
    2619     * Finds the index of the given value in the array.
    2620     * <p>
    2621     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    2622     * </p>
    2623     *
    2624     * @param array the array to search through for the object, may be {@code null}
    2625     * @param valueToFind the value to find
    2626     * @return the index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null}
    2627     *         array input
    2628     */
    2629    public static int indexOf(final long[] array, final long valueToFind) {
    2630        return indexOf(array, valueToFind, 0);
    2631    }
    2632
    2633    /**
    2634     * Finds the index of the given value in the array starting at the given index.
    2635     * <p>
    2636     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    2637     * </p>
    2638     * <p>
    2639     * A negative startIndex is treated as zero. A startIndex larger than the array
    2640     * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
    2641     * </p>
    2642     *
    2643     * @param array  the array to search through for the object, may be {@code null}
    2644     * @param valueToFind  the value to find
    2645     * @param startIndex  the index to start searching at
    2646     * @return the index of the value within the array,
    2647     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    2648     */
    2649    public static int indexOf(final long[] array, final long valueToFind, int startIndex) {
    2650        if (array == null) {
    2651            return INDEX_NOT_FOUND;
    2652        }
    2653        if (startIndex < 0) {
    2654            startIndex = 0;
    2655        }
    2656        for (int i = startIndex; i < array.length; i++) {
    2657            if (valueToFind == array[i]) {
    2658                return i;
    2659            }
    2660        }
    2661        return INDEX_NOT_FOUND;
    2662    }
    2663
    2664    /**
    2665     * Finds the index of the given object in the array.
    2666     * <p>
    2667     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    2668     * </p>
    2669     *
    2670     * @param array  the array to search through for the object, may be {@code null}
    2671     * @param objectToFind  the object to find, may be {@code null}
    2672     * @return the index of the object within the array,
    2673     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    2674     */
    2675    public static int indexOf(final Object[] array, final Object objectToFind) {
    2676        return indexOf(array, objectToFind, 0);
    2677    }
    2678
    2679    /**
    2680     * Finds the index of the given object in the array starting at the given index.
    2681     * <p>
    2682     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    2683     * </p>
    2684     * <p>
    2685     * A negative startIndex is treated as zero. A startIndex larger than the array
    2686     * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
    2687     * </p>
    2688     *
    2689     * @param array  the array to search through for the object, may be {@code null}
    2690     * @param objectToFind  the object to find, may be {@code null}
    2691     * @param startIndex  the index to start searching at
    2692     * @return the index of the object within the array starting at the index,
    2693     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    2694     */
    2695    public static int indexOf(final Object[] array, final Object objectToFind, int startIndex) {
    2696        if (array == null) {
    2697            return INDEX_NOT_FOUND;
    2698        }
    2699        if (startIndex < 0) {
    2700            startIndex = 0;
    2701        }
    2702        if (objectToFind == null) {
    2703            for (int i = startIndex; i < array.length; i++) {
    2704                if (array[i] == null) {
    2705                    return i;
    2706                }
    2707            }
    2708        } else {
    2709            for (int i = startIndex; i < array.length; i++) {
    2710                if (objectToFind.equals(array[i])) {
    2711                    return i;
    2712                }
    2713            }
    2714        }
    2715        return INDEX_NOT_FOUND;
    2716    }
    2717
    2718    /**
    2719     * Finds the index of the given value in the array.
    2720     * <p>
    2721     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    2722     * </p>
    2723     *
    2724     * @param array  the array to search through for the object, may be {@code null}
    2725     * @param valueToFind  the value to find
    2726     * @return the index of the value within the array,
    2727     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    2728     */
    2729    public static int indexOf(final short[] array, final short valueToFind) {
    2730        return indexOf(array, valueToFind, 0);
    2731    }
    2732
    2733    /**
    2734     * Finds the index of the given value in the array starting at the given index.
    2735     * <p>
    2736     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    2737     * </p>
    2738     * <p>
    2739     * A negative startIndex is treated as zero. A startIndex larger than the array
    2740     * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
    2741     * </p>
    2742     *
    2743     * @param array  the array to search through for the object, may be {@code null}
    2744     * @param valueToFind  the value to find
    2745     * @param startIndex  the index to start searching at
    2746     * @return the index of the value within the array,
    2747     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    2748     */
    2749    public static int indexOf(final short[] array, final short valueToFind, int startIndex) {
    2750        if (array == null) {
    2751            return INDEX_NOT_FOUND;
    2752        }
    2753        if (startIndex < 0) {
    2754            startIndex = 0;
    2755        }
    2756        for (int i = startIndex; i < array.length; i++) {
    2757            if (valueToFind == array[i]) {
    2758                return i;
    2759            }
    2760        }
    2761        return INDEX_NOT_FOUND;
    2762    }
    2763
    2764    /**
    2765     * Inserts elements into an array at the given index (starting from zero).
    2766     *
    2767     * <p>When an array is returned, it is always a new array.</p>
    2768     *
    2769     * <pre>
    2770     * ArrayUtils.insert(index, null, null)      = null
    2771     * ArrayUtils.insert(index, array, null)     = cloned copy of 'array'
    2772     * ArrayUtils.insert(index, null, values)    = null
    2773     * </pre>
    2774     *
    2775     * @param index the position within {@code array} to insert the new values
    2776     * @param array the array to insert the values into, may be {@code null}
    2777     * @param values the new values to insert, may be {@code null}
    2778     * @return The new array or {@code null} if the given array is {@code null}.
    2779     * @throws IndexOutOfBoundsException if {@code array} is provided
    2780     * and either {@code index < 0} or {@code index > array.length}
    2781     * @since 3.6
    2782     */
    2783    public static boolean[] insert(final int index, final boolean[] array, final boolean... values) {
    2784        if (array == null) {
    2785            return null;
    2786        }
    2787        if (ArrayUtils.isEmpty(values)) {
    2788            return clone(array);
    2789        }
    2790        if (index < 0 || index > array.length) {
    2791            throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
    2792        }
    2793
    2794        final boolean[] result = new boolean[array.length + values.length];
    2795
    2796        System.arraycopy(values, 0, result, index, values.length);
    2797        if (index > 0) {
    2798            System.arraycopy(array, 0, result, 0, index);
    2799        }
    2800        if (index < array.length) {
    2801            System.arraycopy(array, index, result, index + values.length, array.length - index);
    2802        }
    2803        return result;
    2804    }
    2805
    2806    /**
    2807     * Inserts elements into an array at the given index (starting from zero).
    2808     *
    2809     * <p>When an array is returned, it is always a new array.</p>
    2810     *
    2811     * <pre>
    2812     * ArrayUtils.insert(index, null, null)      = null
    2813     * ArrayUtils.insert(index, array, null)     = cloned copy of 'array'
    2814     * ArrayUtils.insert(index, null, values)    = null
    2815     * </pre>
    2816     *
    2817     * @param index the position within {@code array} to insert the new values
    2818     * @param array the array to insert the values into, may be {@code null}
    2819     * @param values the new values to insert, may be {@code null}
    2820     * @return The new array or {@code null} if the given array is {@code null}.
    2821     * @throws IndexOutOfBoundsException if {@code array} is provided
    2822     * and either {@code index < 0} or {@code index > array.length}
    2823     * @since 3.6
    2824     */
    2825    public static byte[] insert(final int index, final byte[] array, final byte... values) {
    2826        if (array == null) {
    2827            return null;
    2828        }
    2829        if (ArrayUtils.isEmpty(values)) {
    2830            return clone(array);
    2831        }
    2832        if (index < 0 || index > array.length) {
    2833            throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
    2834        }
    2835
    2836        final byte[] result = new byte[array.length + values.length];
    2837
    2838        System.arraycopy(values, 0, result, index, values.length);
    2839        if (index > 0) {
    2840            System.arraycopy(array, 0, result, 0, index);
    2841        }
    2842        if (index < array.length) {
    2843            System.arraycopy(array, index, result, index + values.length, array.length - index);
    2844        }
    2845        return result;
    2846    }
    2847
    2848    /**
    2849     * Inserts elements into an array at the given index (starting from zero).
    2850     *
    2851     * <p>When an array is returned, it is always a new array.</p>
    2852     *
    2853     * <pre>
    2854     * ArrayUtils.insert(index, null, null)      = null
    2855     * ArrayUtils.insert(index, array, null)     = cloned copy of 'array'
    2856     * ArrayUtils.insert(index, null, values)    = null
    2857     * </pre>
    2858     *
    2859     * @param index the position within {@code array} to insert the new values
    2860     * @param array the array to insert the values into, may be {@code null}
    2861     * @param values the new values to insert, may be {@code null}
    2862     * @return The new array or {@code null} if the given array is {@code null}.
    2863     * @throws IndexOutOfBoundsException if {@code array} is provided
    2864     * and either {@code index < 0} or {@code index > array.length}
    2865     * @since 3.6
    2866     */
    2867    public static char[] insert(final int index, final char[] array, final char... values) {
    2868        if (array == null) {
    2869            return null;
    2870        }
    2871        if (ArrayUtils.isEmpty(values)) {
    2872            return clone(array);
    2873        }
    2874        if (index < 0 || index > array.length) {
    2875            throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
    2876        }
    2877
    2878        final char[] result = new char[array.length + values.length];
    2879
    2880        System.arraycopy(values, 0, result, index, values.length);
    2881        if (index > 0) {
    2882            System.arraycopy(array, 0, result, 0, index);
    2883        }
    2884        if (index < array.length) {
    2885            System.arraycopy(array, index, result, index + values.length, array.length - index);
    2886        }
    2887        return result;
    2888    }
    2889
    2890    /**
    2891     * Inserts elements into an array at the given index (starting from zero).
    2892     *
    2893     * <p>When an array is returned, it is always a new array.</p>
    2894     *
    2895     * <pre>
    2896     * ArrayUtils.insert(index, null, null)      = null
    2897     * ArrayUtils.insert(index, array, null)     = cloned copy of 'array'
    2898     * ArrayUtils.insert(index, null, values)    = null
    2899     * </pre>
    2900     *
    2901     * @param index the position within {@code array} to insert the new values
    2902     * @param array the array to insert the values into, may be {@code null}
    2903     * @param values the new values to insert, may be {@code null}
    2904     * @return The new array or {@code null} if the given array is {@code null}.
    2905     * @throws IndexOutOfBoundsException if {@code array} is provided
    2906     * and either {@code index < 0} or {@code index > array.length}
    2907     * @since 3.6
    2908     */
    2909    public static double[] insert(final int index, final double[] array, final double... values) {
    2910        if (array == null) {
    2911            return null;
    2912        }
    2913        if (ArrayUtils.isEmpty(values)) {
    2914            return clone(array);
    2915        }
    2916        if (index < 0 || index > array.length) {
    2917            throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
    2918        }
    2919
    2920        final double[] result = new double[array.length + values.length];
    2921
    2922        System.arraycopy(values, 0, result, index, values.length);
    2923        if (index > 0) {
    2924            System.arraycopy(array, 0, result, 0, index);
    2925        }
    2926        if (index < array.length) {
    2927            System.arraycopy(array, index, result, index + values.length, array.length - index);
    2928        }
    2929        return result;
    2930    }
    2931
    2932    /**
    2933     * Inserts elements into an array at the given index (starting from zero).
    2934     *
    2935     * <p>When an array is returned, it is always a new array.</p>
    2936     *
    2937     * <pre>
    2938     * ArrayUtils.insert(index, null, null)      = null
    2939     * ArrayUtils.insert(index, array, null)     = cloned copy of 'array'
    2940     * ArrayUtils.insert(index, null, values)    = null
    2941     * </pre>
    2942     *
    2943     * @param index the position within {@code array} to insert the new values
    2944     * @param array the array to insert the values into, may be {@code null}
    2945     * @param values the new values to insert, may be {@code null}
    2946     * @return The new array or {@code null} if the given array is {@code null}.
    2947     * @throws IndexOutOfBoundsException if {@code array} is provided
    2948     * and either {@code index < 0} or {@code index > array.length}
    2949     * @since 3.6
    2950     */
    2951    public static float[] insert(final int index, final float[] array, final float... values) {
    2952        if (array == null) {
    2953            return null;
    2954        }
    2955        if (ArrayUtils.isEmpty(values)) {
    2956            return clone(array);
    2957        }
    2958        if (index < 0 || index > array.length) {
    2959            throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
    2960        }
    2961
    2962        final float[] result = new float[array.length + values.length];
    2963
    2964        System.arraycopy(values, 0, result, index, values.length);
    2965        if (index > 0) {
    2966            System.arraycopy(array, 0, result, 0, index);
    2967        }
    2968        if (index < array.length) {
    2969            System.arraycopy(array, index, result, index + values.length, array.length - index);
    2970        }
    2971        return result;
    2972    }
    2973
    2974    /**
    2975     * Inserts elements into an array at the given index (starting from zero).
    2976     *
    2977     * <p>When an array is returned, it is always a new array.</p>
    2978     *
    2979     * <pre>
    2980     * ArrayUtils.insert(index, null, null)      = null
    2981     * ArrayUtils.insert(index, array, null)     = cloned copy of 'array'
    2982     * ArrayUtils.insert(index, null, values)    = null
    2983     * </pre>
    2984     *
    2985     * @param index the position within {@code array} to insert the new values
    2986     * @param array the array to insert the values into, may be {@code null}
    2987     * @param values the new values to insert, may be {@code null}
    2988     * @return The new array or {@code null} if the given array is {@code null}.
    2989     * @throws IndexOutOfBoundsException if {@code array} is provided
    2990     * and either {@code index < 0} or {@code index > array.length}
    2991     * @since 3.6
    2992     */
    2993    public static int[] insert(final int index, final int[] array, final int... values) {
    2994        if (array == null) {
    2995            return null;
    2996        }
    2997        if (ArrayUtils.isEmpty(values)) {
    2998            return clone(array);
    2999        }
    3000        if (index < 0 || index > array.length) {
    3001            throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
    3002        }
    3003
    3004        final int[] result = new int[array.length + values.length];
    3005
    3006        System.arraycopy(values, 0, result, index, values.length);
    3007        if (index > 0) {
    3008            System.arraycopy(array, 0, result, 0, index);
    3009        }
    3010        if (index < array.length) {
    3011            System.arraycopy(array, index, result, index + values.length, array.length - index);
    3012        }
    3013        return result;
    3014    }
    3015
    3016    /**
    3017     * Inserts elements into an array at the given index (starting from zero).
    3018     *
    3019     * <p>When an array is returned, it is always a new array.</p>
    3020     *
    3021     * <pre>
    3022     * ArrayUtils.insert(index, null, null)      = null
    3023     * ArrayUtils.insert(index, array, null)     = cloned copy of 'array'
    3024     * ArrayUtils.insert(index, null, values)    = null
    3025     * </pre>
    3026     *
    3027     * @param index the position within {@code array} to insert the new values
    3028     * @param array the array to insert the values into, may be {@code null}
    3029     * @param values the new values to insert, may be {@code null}
    3030     * @return The new array or {@code null} if the given array is {@code null}.
    3031     * @throws IndexOutOfBoundsException if {@code array} is provided
    3032     * and either {@code index < 0} or {@code index > array.length}
    3033     * @since 3.6
    3034     */
    3035    public static long[] insert(final int index, final long[] array, final long... values) {
    3036        if (array == null) {
    3037            return null;
    3038        }
    3039        if (ArrayUtils.isEmpty(values)) {
    3040            return clone(array);
    3041        }
    3042        if (index < 0 || index > array.length) {
    3043            throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
    3044        }
    3045
    3046        final long[] result = new long[array.length + values.length];
    3047
    3048        System.arraycopy(values, 0, result, index, values.length);
    3049        if (index > 0) {
    3050            System.arraycopy(array, 0, result, 0, index);
    3051        }
    3052        if (index < array.length) {
    3053            System.arraycopy(array, index, result, index + values.length, array.length - index);
    3054        }
    3055        return result;
    3056    }
    3057
    3058    /**
    3059     * Inserts elements into an array at the given index (starting from zero).
    3060     *
    3061     * <p>When an array is returned, it is always a new array.</p>
    3062     *
    3063     * <pre>
    3064     * ArrayUtils.insert(index, null, null)      = null
    3065     * ArrayUtils.insert(index, array, null)     = cloned copy of 'array'
    3066     * ArrayUtils.insert(index, null, values)    = null
    3067     * </pre>
    3068     *
    3069     * @param index the position within {@code array} to insert the new values
    3070     * @param array the array to insert the values into, may be {@code null}
    3071     * @param values the new values to insert, may be {@code null}
    3072     * @return The new array or {@code null} if the given array is {@code null}.
    3073     * @throws IndexOutOfBoundsException if {@code array} is provided
    3074     * and either {@code index < 0} or {@code index > array.length}
    3075     * @since 3.6
    3076     */
    3077    public static short[] insert(final int index, final short[] array, final short... values) {
    3078        if (array == null) {
    3079            return null;
    3080        }
    3081        if (ArrayUtils.isEmpty(values)) {
    3082            return clone(array);
    3083        }
    3084        if (index < 0 || index > array.length) {
    3085            throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
    3086        }
    3087
    3088        final short[] result = new short[array.length + values.length];
    3089
    3090        System.arraycopy(values, 0, result, index, values.length);
    3091        if (index > 0) {
    3092            System.arraycopy(array, 0, result, 0, index);
    3093        }
    3094        if (index < array.length) {
    3095            System.arraycopy(array, index, result, index + values.length, array.length - index);
    3096        }
    3097        return result;
    3098    }
    3099
    3100    /**
    3101     * Inserts elements into an array at the given index (starting from zero).
    3102     *
    3103     * <p>When an array is returned, it is always a new array.</p>
    3104     *
    3105     * <pre>
    3106     * ArrayUtils.insert(index, null, null)      = null
    3107     * ArrayUtils.insert(index, array, null)     = cloned copy of 'array'
    3108     * ArrayUtils.insert(index, null, values)    = null
    3109     * </pre>
    3110     *
    3111     * @param <T> The type of elements in {@code array} and {@code values}
    3112     * @param index the position within {@code array} to insert the new values
    3113     * @param array the array to insert the values into, may be {@code null}
    3114     * @param values the new values to insert, may be {@code null}
    3115     * @return The new array or {@code null} if the given array is {@code null}.
    3116     * @throws IndexOutOfBoundsException if {@code array} is provided
    3117     * and either {@code index < 0} or {@code index > array.length}
    3118     * @since 3.6
    3119     */
    3120    @SafeVarargs
    3121    public static <T> T[] insert(final int index, final T[] array, final T... values) {
    3122        /*
    3123         * Note on use of @SafeVarargs:
    3124         *
    3125         * By returning null when 'array' is null, we avoid returning the vararg
    3126         * array to the caller. We also avoid relying on the type of the vararg
    3127         * array, by inspecting the component type of 'array'.
    3128         */
    3129
    3130        if (array == null) {
    3131            return null;
    3132        }
    3133        if (ArrayUtils.isEmpty(values)) {
    3134            return clone(array);
    3135        }
    3136        if (index < 0 || index > array.length) {
    3137            throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
    3138        }
    3139
    3140        final Class<T> type = getComponentType(array);
    3141        final int length = array.length + values.length;
    3142        final T[] result = newInstance(type, length);
    3143
    3144        System.arraycopy(values, 0, result, index, values.length);
    3145        if (index > 0) {
    3146            System.arraycopy(array, 0, result, 0, index);
    3147        }
    3148        if (index < array.length) {
    3149            System.arraycopy(array, index, result, index + values.length, array.length - index);
    3150        }
    3151        return result;
    3152    }
    3153
    3154    /**
    3155     * Checks if an array is empty or {@code null}.
    3156     *
    3157     * @param array the array to test
    3158     * @return {@code true} if the array is empty or {@code null}
    3159     */
    3160    private static boolean isArrayEmpty(final Object array) {
    3161        return getLength(array) == 0;
    3162    }
    3163
    3164    /**
    3165     * Returns whether a given array can safely be accessed at the given index.
    3166     *
    3167     * <pre>
    3168     * ArrayUtils.isArrayIndexValid(null, 0)       = false
    3169     * ArrayUtils.isArrayIndexValid([], 0)         = false
    3170     * ArrayUtils.isArrayIndexValid(["a"], 0)      = true
    3171     * </pre>
    3172     *
    3173     * @param <T> the component type of the array
    3174     * @param array the array to inspect, may be null
    3175     * @param index the index of the array to be inspected
    3176     * @return Whether the given index is safely-accessible in the given array
    3177     * @since 3.8
    3178     */
    3179    public static <T> boolean isArrayIndexValid(final T[] array, final int index) {
    3180        return index >= 0 && getLength(array) > index;
    3181    }
    3182
    3183    /**
    3184     * Checks if an array of primitive booleans is empty or {@code null}.
    3185     *
    3186     * @param array  the array to test
    3187     * @return {@code true} if the array is empty or {@code null}
    3188     * @since 2.1
    3189     */
    3190    public static boolean isEmpty(final boolean[] array) {
    3191        return isArrayEmpty(array);
    3192    }
    3193
    3194    /**
    3195     * Checks if an array of primitive bytes is empty or {@code null}.
    3196     *
    3197     * @param array  the array to test
    3198     * @return {@code true} if the array is empty or {@code null}
    3199     * @since 2.1
    3200     */
    3201    public static boolean isEmpty(final byte[] array) {
    3202        return isArrayEmpty(array);
    3203    }
    3204
    3205    /**
    3206     * Checks if an array of primitive chars is empty or {@code null}.
    3207     *
    3208     * @param array  the array to test
    3209     * @return {@code true} if the array is empty or {@code null}
    3210     * @since 2.1
    3211     */
    3212    public static boolean isEmpty(final char[] array) {
    3213        return isArrayEmpty(array);
    3214    }
    3215
    3216    /**
    3217     * Checks if an array of primitive doubles is empty or {@code null}.
    3218     *
    3219     * @param array  the array to test
    3220     * @return {@code true} if the array is empty or {@code null}
    3221     * @since 2.1
    3222     */
    3223    public static boolean isEmpty(final double[] array) {
    3224        return isArrayEmpty(array);
    3225    }
    3226
    3227    /**
    3228     * Checks if an array of primitive floats is empty or {@code null}.
    3229     *
    3230     * @param array  the array to test
    3231     * @return {@code true} if the array is empty or {@code null}
    3232     * @since 2.1
    3233     */
    3234    public static boolean isEmpty(final float[] array) {
    3235        return isArrayEmpty(array);
    3236    }
    3237
    3238    /**
    3239     * Checks if an array of primitive ints is empty or {@code null}.
    3240     *
    3241     * @param array  the array to test
    3242     * @return {@code true} if the array is empty or {@code null}
    3243     * @since 2.1
    3244     */
    3245    public static boolean isEmpty(final int[] array) {
    3246        return isArrayEmpty(array);
    3247    }
    3248
    3249    /**
    3250     * Checks if an array of primitive longs is empty or {@code null}.
    3251     *
    3252     * @param array  the array to test
    3253     * @return {@code true} if the array is empty or {@code null}
    3254     * @since 2.1
    3255     */
    3256    public static boolean isEmpty(final long[] array) {
    3257        return isArrayEmpty(array);
    3258    }
    3259
    3260    /**
    3261     * Checks if an array of Objects is empty or {@code null}.
    3262     *
    3263     * @param array  the array to test
    3264     * @return {@code true} if the array is empty or {@code null}
    3265     * @since 2.1
    3266     */
    3267    public static boolean isEmpty(final Object[] array) {
    3268        return isArrayEmpty(array);
    3269    }
    3270
    3271    /**
    3272     * Checks if an array of primitive shorts is empty or {@code null}.
    3273     *
    3274     * @param array  the array to test
    3275     * @return {@code true} if the array is empty or {@code null}
    3276     * @since 2.1
    3277     */
    3278    public static boolean isEmpty(final short[] array) {
    3279        return isArrayEmpty(array);
    3280    }
    3281
    3282    /**
    3283     * Compares two arrays, using equals(), handling multi-dimensional arrays
    3284     * correctly.
    3285     * <p>
    3286     * Multi-dimensional primitive arrays are also handled correctly by this method.
    3287     * </p>
    3288     *
    3289     * @param array1  the left-hand array to compare, may be {@code null}
    3290     * @param array2  the right-hand array to compare, may be {@code null}
    3291     * @return {@code true} if the arrays are equal
    3292     * @deprecated this method has been replaced by {@code java.util.Objects.deepEquals(Object, Object)} and will be
    3293     * removed from future releases.
    3294     */
    3295    @Deprecated
    3296    public static boolean isEquals(final Object array1, final Object array2) {
    3297        return new EqualsBuilder().append(array1, array2).isEquals();
    3298    }
    3299
    3300    /**
    3301     * Checks if an array of primitive booleans is not empty and not {@code null}.
    3302     *
    3303     * @param array  the array to test
    3304     * @return {@code true} if the array is not empty and not {@code null}
    3305     * @since 2.5
    3306     */
    3307    public static boolean isNotEmpty(final boolean[] array) {
    3308        return !isEmpty(array);
    3309    }
    3310
    3311    /**
    3312     * Checks if an array of primitive bytes is not empty and not {@code null}.
    3313     *
    3314     * @param array  the array to test
    3315     * @return {@code true} if the array is not empty and not {@code null}
    3316     * @since 2.5
    3317     */
    3318    public static boolean isNotEmpty(final byte[] array) {
    3319        return !isEmpty(array);
    3320    }
    3321
    3322    /**
    3323     * Checks if an array of primitive chars is not empty and not {@code null}.
    3324     *
    3325     * @param array  the array to test
    3326     * @return {@code true} if the array is not empty and not {@code null}
    3327     * @since 2.5
    3328     */
    3329    public static boolean isNotEmpty(final char[] array) {
    3330        return !isEmpty(array);
    3331    }
    3332
    3333    /**
    3334     * Checks if an array of primitive doubles is not empty and not {@code null}.
    3335     *
    3336     * @param array  the array to test
    3337     * @return {@code true} if the array is not empty and not {@code null}
    3338     * @since 2.5
    3339     */
    3340    public static boolean isNotEmpty(final double[] array) {
    3341        return !isEmpty(array);
    3342    }
    3343
    3344    /**
    3345     * Checks if an array of primitive floats is not empty and not {@code null}.
    3346     *
    3347     * @param array  the array to test
    3348     * @return {@code true} if the array is not empty and not {@code null}
    3349     * @since 2.5
    3350     */
    3351    public static boolean isNotEmpty(final float[] array) {
    3352        return !isEmpty(array);
    3353    }
    3354
    3355    /**
    3356     * Checks if an array of primitive ints is not empty and not {@code null}.
    3357     *
    3358     * @param array  the array to test
    3359     * @return {@code true} if the array is not empty and not {@code null}
    3360     * @since 2.5
    3361     */
    3362    public static boolean isNotEmpty(final int[] array) {
    3363        return !isEmpty(array);
    3364    }
    3365
    3366    /**
    3367     * Checks if an array of primitive longs is not empty and not {@code null}.
    3368     *
    3369     * @param array  the array to test
    3370     * @return {@code true} if the array is not empty and not {@code null}
    3371     * @since 2.5
    3372     */
    3373    public static boolean isNotEmpty(final long[] array) {
    3374        return !isEmpty(array);
    3375    }
    3376
    3377    /**
    3378     * Checks if an array of primitive shorts is not empty and not {@code null}.
    3379     *
    3380     * @param array  the array to test
    3381     * @return {@code true} if the array is not empty and not {@code null}
    3382     * @since 2.5
    3383     */
    3384    public static boolean isNotEmpty(final short[] array) {
    3385        return !isEmpty(array);
    3386    }
    3387
    3388    /**
    3389     * Checks if an array of Objects is not empty and not {@code null}.
    3390     *
    3391     * @param <T> the component type of the array
    3392     * @param array  the array to test
    3393     * @return {@code true} if the array is not empty and not {@code null}
    3394     * @since 2.5
    3395     */
    3396     public static <T> boolean isNotEmpty(final T[] array) {
    3397         return !isEmpty(array);
    3398     }
    3399
    3400    /**
    3401     * Checks whether two arrays are the same length, treating
    3402     * {@code null} arrays as length {@code 0}.
    3403     *
    3404     * @param array1 the first array, may be {@code null}
    3405     * @param array2 the second array, may be {@code null}
    3406     * @return {@code true} if length of arrays matches, treating
    3407     *  {@code null} as an empty array
    3408     */
    3409    public static boolean isSameLength(final boolean[] array1, final boolean[] array2) {
    3410        return getLength(array1) == getLength(array2);
    3411    }
    3412
    3413    /**
    3414     * Checks whether two arrays are the same length, treating
    3415     * {@code null} arrays as length {@code 0}.
    3416     *
    3417     * @param array1 the first array, may be {@code null}
    3418     * @param array2 the second array, may be {@code null}
    3419     * @return {@code true} if length of arrays matches, treating
    3420     *  {@code null} as an empty array
    3421     */
    3422    public static boolean isSameLength(final byte[] array1, final byte[] array2) {
    3423        return getLength(array1) == getLength(array2);
    3424    }
    3425
    3426    /**
    3427     * Checks whether two arrays are the same length, treating
    3428     * {@code null} arrays as length {@code 0}.
    3429     *
    3430     * @param array1 the first array, may be {@code null}
    3431     * @param array2 the second array, may be {@code null}
    3432     * @return {@code true} if length of arrays matches, treating
    3433     *  {@code null} as an empty array
    3434     */
    3435    public static boolean isSameLength(final char[] array1, final char[] array2) {
    3436        return getLength(array1) == getLength(array2);
    3437    }
    3438
    3439    /**
    3440     * Checks whether two arrays are the same length, treating
    3441     * {@code null} arrays as length {@code 0}.
    3442     *
    3443     * @param array1 the first array, may be {@code null}
    3444     * @param array2 the second array, may be {@code null}
    3445     * @return {@code true} if length of arrays matches, treating
    3446     *  {@code null} as an empty array
    3447     */
    3448    public static boolean isSameLength(final double[] array1, final double[] array2) {
    3449        return getLength(array1) == getLength(array2);
    3450    }
    3451
    3452    /**
    3453     * Checks whether two arrays are the same length, treating
    3454     * {@code null} arrays as length {@code 0}.
    3455     *
    3456     * @param array1 the first array, may be {@code null}
    3457     * @param array2 the second array, may be {@code null}
    3458     * @return {@code true} if length of arrays matches, treating
    3459     *  {@code null} as an empty array
    3460     */
    3461    public static boolean isSameLength(final float[] array1, final float[] array2) {
    3462        return getLength(array1) == getLength(array2);
    3463    }
    3464
    3465    /**
    3466     * Checks whether two arrays are the same length, treating
    3467     * {@code null} arrays as length {@code 0}.
    3468     *
    3469     * @param array1 the first array, may be {@code null}
    3470     * @param array2 the second array, may be {@code null}
    3471     * @return {@code true} if length of arrays matches, treating
    3472     *  {@code null} as an empty array
    3473     */
    3474    public static boolean isSameLength(final int[] array1, final int[] array2) {
    3475        return getLength(array1) == getLength(array2);
    3476    }
    3477
    3478    /**
    3479     * Checks whether two arrays are the same length, treating
    3480     * {@code null} arrays as length {@code 0}.
    3481     *
    3482     * @param array1 the first array, may be {@code null}
    3483     * @param array2 the second array, may be {@code null}
    3484     * @return {@code true} if length of arrays matches, treating
    3485     *  {@code null} as an empty array
    3486     */
    3487    public static boolean isSameLength(final long[] array1, final long[] array2) {
    3488        return getLength(array1) == getLength(array2);
    3489    }
    3490
    3491    /**
    3492     * Checks whether two arrays are the same length, treating
    3493     * {@code null} arrays as length {@code 0}.
    3494     * <p>
    3495     * Any multi-dimensional aspects of the arrays are ignored.
    3496     * </p>
    3497     *
    3498     * @param array1 the first array, may be {@code null}
    3499     * @param array2 the second array, may be {@code null}
    3500     * @return {@code true} if length of arrays matches, treating
    3501     *  {@code null} as an empty array
    3502     * @since 3.11
    3503     */
    3504    public static boolean isSameLength(final Object array1, final Object array2) {
    3505        return getLength(array1) == getLength(array2);
    3506    }
    3507
    3508    /**
    3509     * Checks whether two arrays are the same length, treating
    3510     * {@code null} arrays as length {@code 0}.
    3511     * <p>
    3512     * Any multi-dimensional aspects of the arrays are ignored.
    3513     * </p>
    3514     *
    3515     * @param array1 the first array, may be {@code null}
    3516     * @param array2 the second array, may be {@code null}
    3517     * @return {@code true} if length of arrays matches, treating
    3518     *  {@code null} as an empty array
    3519     */
    3520    public static boolean isSameLength(final Object[] array1, final Object[] array2) {
    3521        return getLength(array1) == getLength(array2);
    3522    }
    3523
    3524
    3525    /**
    3526     * Checks whether two arrays are the same length, treating
    3527     * {@code null} arrays as length {@code 0}.
    3528     *
    3529     * @param array1 the first array, may be {@code null}
    3530     * @param array2 the second array, may be {@code null}
    3531     * @return {@code true} if length of arrays matches, treating
    3532     *  {@code null} as an empty array
    3533     */
    3534    public static boolean isSameLength(final short[] array1, final short[] array2) {
    3535        return getLength(array1) == getLength(array2);
    3536    }
    3537
    3538    /**
    3539     * Checks whether two arrays are the same type taking into account
    3540     * multidimensional arrays.
    3541     *
    3542     * @param array1 the first array, must not be {@code null}
    3543     * @param array2 the second array, must not be {@code null}
    3544     * @return {@code true} if type of arrays matches
    3545     * @throws IllegalArgumentException if either array is {@code null}
    3546     */
    3547    public static boolean isSameType(final Object array1, final Object array2) {
    3548        if (array1 == null || array2 == null) {
    3549            throw new IllegalArgumentException("The Array must not be null");
    3550        }
    3551        return array1.getClass().getName().equals(array2.getClass().getName());
    3552    }
    3553
    3554    /**
    3555     * This method checks whether the provided array is sorted according to natural ordering
    3556     * ({@code false} before {@code true}).
    3557     *
    3558     * @param array the array to check
    3559     * @return whether the array is sorted according to natural ordering
    3560     * @since 3.4
    3561     */
    3562    public static boolean isSorted(final boolean[] array) {
    3563        if (getLength(array) < 2) {
    3564            return true;
    3565        }
    3566
    3567        boolean previous = array[0];
    3568        final int n = array.length;
    3569        for (int i = 1; i < n; i++) {
    3570            final boolean current = array[i];
    3571            if (BooleanUtils.compare(previous, current) > 0) {
    3572                return false;
    3573            }
    3574
    3575            previous = current;
    3576        }
    3577        return true;
    3578    }
    3579
    3580    /**
    3581     * Checks whether the provided array is sorted according to natural ordering.
    3582     *
    3583     * @param array the array to check
    3584     * @return whether the array is sorted according to natural ordering
    3585     * @since 3.4
    3586     */
    3587    public static boolean isSorted(final byte[] array) {
    3588        if (getLength(array) < 2) {
    3589            return true;
    3590        }
    3591
    3592        byte previous = array[0];
    3593        final int n = array.length;
    3594        for (int i = 1; i < n; i++) {
    3595            final byte current = array[i];
    3596            if (NumberUtils.compare(previous, current) > 0) {
    3597                return false;
    3598            }
    3599
    3600            previous = current;
    3601        }
    3602        return true;
    3603    }
    3604
    3605    /**
    3606     * Checks whether the provided array is sorted according to natural ordering.
    3607     *
    3608     * @param array the array to check
    3609     * @return whether the array is sorted according to natural ordering
    3610     * @since 3.4
    3611     */
    3612    public static boolean isSorted(final char[] array) {
    3613        if (getLength(array) < 2) {
    3614            return true;
    3615        }
    3616
    3617        char previous = array[0];
    3618        final int n = array.length;
    3619        for (int i = 1; i < n; i++) {
    3620            final char current = array[i];
    3621            if (CharUtils.compare(previous, current) > 0) {
    3622                return false;
    3623            }
    3624
    3625            previous = current;
    3626        }
    3627        return true;
    3628    }
    3629
    3630    /**
    3631     * This method checks whether the provided array is sorted according to natural ordering.
    3632     *
    3633     * @param array the array to check
    3634     * @return whether the array is sorted according to natural ordering
    3635     * @since 3.4
    3636     */
    3637    public static boolean isSorted(final double[] array) {
    3638        if (getLength(array) < 2) {
    3639            return true;
    3640        }
    3641
    3642        double previous = array[0];
    3643        final int n = array.length;
    3644        for (int i = 1; i < n; i++) {
    3645            final double current = array[i];
    3646            if (Double.compare(previous, current) > 0) {
    3647                return false;
    3648            }
    3649
    3650            previous = current;
    3651        }
    3652        return true;
    3653    }
    3654
    3655    /**
    3656     * This method checks whether the provided array is sorted according to natural ordering.
    3657     *
    3658     * @param array the array to check
    3659     * @return whether the array is sorted according to natural ordering
    3660     * @since 3.4
    3661     */
    3662    public static boolean isSorted(final float[] array) {
    3663        if (getLength(array) < 2) {
    3664            return true;
    3665        }
    3666
    3667        float previous = array[0];
    3668        final int n = array.length;
    3669        for (int i = 1; i < n; i++) {
    3670            final float current = array[i];
    3671            if (Float.compare(previous, current) > 0) {
    3672                return false;
    3673            }
    3674
    3675            previous = current;
    3676        }
    3677        return true;
    3678    }
    3679
    3680    /**
    3681     * This method checks whether the provided array is sorted according to natural ordering.
    3682     *
    3683     * @param array the array to check
    3684     * @return whether the array is sorted according to natural ordering
    3685     * @since 3.4
    3686     */
    3687    public static boolean isSorted(final int[] array) {
    3688        if (getLength(array) < 2) {
    3689            return true;
    3690        }
    3691
    3692        int previous = array[0];
    3693        final int n = array.length;
    3694        for (int i = 1; i < n; i++) {
    3695            final int current = array[i];
    3696            if (NumberUtils.compare(previous, current) > 0) {
    3697                return false;
    3698            }
    3699
    3700            previous = current;
    3701        }
    3702        return true;
    3703    }
    3704
    3705    /**
    3706     * This method checks whether the provided array is sorted according to natural ordering.
    3707     *
    3708     * @param array the array to check
    3709     * @return whether the array is sorted according to natural ordering
    3710     * @since 3.4
    3711     */
    3712    public static boolean isSorted(final long[] array) {
    3713        if (getLength(array) < 2) {
    3714            return true;
    3715        }
    3716
    3717        long previous = array[0];
    3718        final int n = array.length;
    3719        for (int i = 1; i < n; i++) {
    3720            final long current = array[i];
    3721            if (NumberUtils.compare(previous, current) > 0) {
    3722                return false;
    3723            }
    3724
    3725            previous = current;
    3726        }
    3727        return true;
    3728    }
    3729
    3730    /**
    3731     * This method checks whether the provided array is sorted according to natural ordering.
    3732     *
    3733     * @param array the array to check
    3734     * @return whether the array is sorted according to natural ordering
    3735     * @since 3.4
    3736     */
    3737    public static boolean isSorted(final short[] array) {
    3738        if (getLength(array) < 2) {
    3739            return true;
    3740        }
    3741
    3742        short previous = array[0];
    3743        final int n = array.length;
    3744        for (int i = 1; i < n; i++) {
    3745            final short current = array[i];
    3746            if (NumberUtils.compare(previous, current) > 0) {
    3747                return false;
    3748            }
    3749
    3750            previous = current;
    3751        }
    3752        return true;
    3753    }
    3754
    3755    /**
    3756     * This method checks whether the provided array is sorted according to the class's
    3757     * {@code compareTo} method.
    3758     *
    3759     * @param array the array to check
    3760     * @param <T> the datatype of the array to check, it must implement {@link Comparable}
    3761     * @return whether the array is sorted
    3762     * @since 3.4
    3763     */
    3764    public static <T extends Comparable<? super T>> boolean isSorted(final T[] array) {
    3765        return isSorted(array, Comparable::compareTo);
    3766    }
    3767
    3768    /**
    3769     * This method checks whether the provided array is sorted according to the provided {@link Comparator}.
    3770     *
    3771     * @param array the array to check
    3772     * @param comparator the {@link Comparator} to compare over
    3773     * @param <T> the datatype of the array
    3774     * @return whether the array is sorted
    3775     * @throws NullPointerException if {@code comparator} is {@code null}
    3776     * @since 3.4
    3777     */
    3778    public static <T> boolean isSorted(final T[] array, final Comparator<T> comparator) {
    3779        Objects.requireNonNull(comparator, "comparator");
    3780        if (getLength(array) < 2) {
    3781            return true;
    3782        }
    3783        T previous = array[0];
    3784        final int n = array.length;
    3785        for (int i = 1; i < n; i++) {
    3786            final T current = array[i];
    3787            if (comparator.compare(previous, current) > 0) {
    3788                return false;
    3789            }
    3790
    3791            previous = current;
    3792        }
    3793        return true;
    3794    }
    3795
    3796    /**
    3797     * Finds the last index of the given value within the array.
    3798     * <p>
    3799     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) if
    3800     * {@code null} array input.
    3801     * </p>
    3802     *
    3803     * @param array  the array to traverse backwards looking for the object, may be {@code null}
    3804     * @param valueToFind  the object to find
    3805     * @return the last index of the value within the array,
    3806     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    3807     */
    3808    public static int lastIndexOf(final boolean[] array, final boolean valueToFind) {
    3809        return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
    3810    }
    3811
    3812    /**
    3813     * Finds the last index of the given value in the array starting at the given index.
    3814     * <p>
    3815     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    3816     * </p>
    3817     * <p>
    3818     * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than
    3819     * the array length will search from the end of the array.
    3820     * </p>
    3821     *
    3822     * @param array  the array to traverse for looking for the object, may be {@code null}
    3823     * @param valueToFind  the value to find
    3824     * @param startIndex  the start index to traverse backwards from
    3825     * @return the last index of the value within the array,
    3826     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    3827     */
    3828    public static int lastIndexOf(final boolean[] array, final boolean valueToFind, int startIndex) {
    3829        if (isEmpty(array) || startIndex < 0) {
    3830            return INDEX_NOT_FOUND;
    3831        }
    3832        if (startIndex >= array.length) {
    3833            startIndex = array.length - 1;
    3834        }
    3835        for (int i = startIndex; i >= 0; i--) {
    3836            if (valueToFind == array[i]) {
    3837                return i;
    3838            }
    3839        }
    3840        return INDEX_NOT_FOUND;
    3841    }
    3842
    3843    /**
    3844     * Finds the last index of the given value within the array.
    3845     * <p>
    3846     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    3847     * </p>
    3848     *
    3849     * @param array  the array to traverse backwards looking for the object, may be {@code null}
    3850     * @param valueToFind  the object to find
    3851     * @return the last index of the value within the array,
    3852     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    3853     */
    3854    public static int lastIndexOf(final byte[] array, final byte valueToFind) {
    3855        return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
    3856    }
    3857
    3858    /**
    3859     * Finds the last index of the given value in the array starting at the given index.
    3860     * <p>
    3861     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    3862     * </p>
    3863     * <p>
    3864     * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
    3865     * array length will search from the end of the array.
    3866     * </p>
    3867     *
    3868     * @param array  the array to traverse for looking for the object, may be {@code null}
    3869     * @param valueToFind  the value to find
    3870     * @param startIndex  the start index to traverse backwards from
    3871     * @return the last index of the value within the array,
    3872     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    3873     */
    3874    public static int lastIndexOf(final byte[] array, final byte valueToFind, int startIndex) {
    3875        if (array == null || startIndex < 0) {
    3876            return INDEX_NOT_FOUND;
    3877        }
    3878        if (startIndex >= array.length) {
    3879            startIndex = array.length - 1;
    3880        }
    3881        for (int i = startIndex; i >= 0; i--) {
    3882            if (valueToFind == array[i]) {
    3883                return i;
    3884            }
    3885        }
    3886        return INDEX_NOT_FOUND;
    3887    }
    3888
    3889    /**
    3890     * Finds the last index of the given value within the array.
    3891     * <p>
    3892     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    3893     * </p>
    3894     *
    3895     * @param array  the array to traverse backwards looking for the object, may be {@code null}
    3896     * @param valueToFind  the object to find
    3897     * @return the last index of the value within the array,
    3898     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    3899     * @since 2.1
    3900     */
    3901    public static int lastIndexOf(final char[] array, final char valueToFind) {
    3902        return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
    3903    }
    3904
    3905    /**
    3906     * Finds the last index of the given value in the array starting at the given index.
    3907     * <p>
    3908     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    3909     * </p>
    3910     * <p>
    3911     * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
    3912     * array length will search from the end of the array.
    3913     * </p>
    3914     *
    3915     * @param array  the array to traverse for looking for the object, may be {@code null}
    3916     * @param valueToFind  the value to find
    3917     * @param startIndex  the start index to traverse backwards from
    3918     * @return the last index of the value within the array,
    3919     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    3920     * @since 2.1
    3921     */
    3922    public static int lastIndexOf(final char[] array, final char valueToFind, int startIndex) {
    3923        if (array == null || startIndex < 0) {
    3924            return INDEX_NOT_FOUND;
    3925        }
    3926        if (startIndex >= array.length) {
    3927            startIndex = array.length - 1;
    3928        }
    3929        for (int i = startIndex; i >= 0; i--) {
    3930            if (valueToFind == array[i]) {
    3931                return i;
    3932            }
    3933        }
    3934        return INDEX_NOT_FOUND;
    3935    }
    3936
    3937    /**
    3938     * Finds the last index of the given value within the array.
    3939     * <p>
    3940     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    3941     * </p>
    3942     *
    3943     * @param array  the array to traverse backwards looking for the object, may be {@code null}
    3944     * @param valueToFind  the object to find
    3945     * @return the last index of the value within the array,
    3946     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    3947     */
    3948    public static int lastIndexOf(final double[] array, final double valueToFind) {
    3949        return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
    3950    }
    3951
    3952    /**
    3953     * Finds the last index of the given value within a given tolerance in the array.
    3954     * This method will return the index of the last value which falls between the region
    3955     * defined by valueToFind - tolerance and valueToFind + tolerance.
    3956     * <p>
    3957     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    3958     * </p>
    3959     *
    3960     * @param array  the array to search through for the object, may be {@code null}
    3961     * @param valueToFind  the value to find
    3962     * @param tolerance tolerance of the search
    3963     * @return the index of the value within the array,
    3964     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    3965     */
    3966    public static int lastIndexOf(final double[] array, final double valueToFind, final double tolerance) {
    3967        return lastIndexOf(array, valueToFind, Integer.MAX_VALUE, tolerance);
    3968    }
    3969
    3970    /**
    3971     * Finds the last index of the given value in the array starting at the given index.
    3972     * <p>
    3973     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    3974     * </p>
    3975     * <p>
    3976     * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
    3977     * array length will search from the end of the array.
    3978     * </p>
    3979     *
    3980     * @param array  the array to traverse for looking for the object, may be {@code null}
    3981     * @param valueToFind  the value to find
    3982     * @param startIndex  the start index to traverse backwards from
    3983     * @return the last index of the value within the array,
    3984     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    3985     */
    3986    public static int lastIndexOf(final double[] array, final double valueToFind, int startIndex) {
    3987        if (isEmpty(array) || startIndex < 0) {
    3988            return INDEX_NOT_FOUND;
    3989        }
    3990        if (startIndex >= array.length) {
    3991            startIndex = array.length - 1;
    3992        }
    3993        for (int i = startIndex; i >= 0; i--) {
    3994            if (valueToFind == array[i]) {
    3995                return i;
    3996            }
    3997        }
    3998        return INDEX_NOT_FOUND;
    3999    }
    4000
    4001    /**
    4002     * Finds the last index of the given value in the array starting at the given index.
    4003     * This method will return the index of the last value which falls between the region
    4004     * defined by valueToFind - tolerance and valueToFind + tolerance.
    4005     * <p>
    4006     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    4007     * </p>
    4008     * <p>
    4009     * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
    4010     * array length will search from the end of the array.
    4011     * </p>
    4012     *
    4013     * @param array  the array to traverse for looking for the object, may be {@code null}
    4014     * @param valueToFind  the value to find
    4015     * @param startIndex  the start index to traverse backwards from
    4016     * @param tolerance  search for value within plus/minus this amount
    4017     * @return the last index of the value within the array,
    4018     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    4019     */
    4020    public static int lastIndexOf(final double[] array, final double valueToFind, int startIndex, final double tolerance) {
    4021        if (isEmpty(array) || startIndex < 0) {
    4022            return INDEX_NOT_FOUND;
    4023        }
    4024        if (startIndex >= array.length) {
    4025            startIndex = array.length - 1;
    4026        }
    4027        final double min = valueToFind - tolerance;
    4028        final double max = valueToFind + tolerance;
    4029        for (int i = startIndex; i >= 0; i--) {
    4030            if (array[i] >= min && array[i] <= max) {
    4031                return i;
    4032            }
    4033        }
    4034        return INDEX_NOT_FOUND;
    4035    }
    4036
    4037    /**
    4038     * Finds the last index of the given value within the array.
    4039     * <p>
    4040     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    4041     * </p>
    4042     *
    4043     * @param array  the array to traverse backwards looking for the object, may be {@code null}
    4044     * @param valueToFind  the object to find
    4045     * @return the last index of the value within the array,
    4046     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    4047     */
    4048    public static int lastIndexOf(final float[] array, final float valueToFind) {
    4049        return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
    4050    }
    4051
    4052    /**
    4053     * Finds the last index of the given value in the array starting at the given index.
    4054     * <p>
    4055     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    4056     * </p>
    4057     * <p>
    4058     * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
    4059     * array length will search from the end of the array.
    4060     * </p>
    4061     *
    4062     * @param array  the array to traverse for looking for the object, may be {@code null}
    4063     * @param valueToFind  the value to find
    4064     * @param startIndex  the start index to traverse backwards from
    4065     * @return the last index of the value within the array,
    4066     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    4067     */
    4068    public static int lastIndexOf(final float[] array, final float valueToFind, int startIndex) {
    4069        if (isEmpty(array) || startIndex < 0) {
    4070            return INDEX_NOT_FOUND;
    4071        }
    4072        if (startIndex >= array.length) {
    4073            startIndex = array.length - 1;
    4074        }
    4075        for (int i = startIndex; i >= 0; i--) {
    4076            if (valueToFind == array[i]) {
    4077                return i;
    4078            }
    4079        }
    4080        return INDEX_NOT_FOUND;
    4081    }
    4082
    4083
    4084    /**
    4085     * Finds the last index of the given value within the array.
    4086     * <p>
    4087     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    4088     * </p>
    4089     *
    4090     * @param array  the array to traverse backwards looking for the object, may be {@code null}
    4091     * @param valueToFind  the object to find
    4092     * @return the last index of the value within the array,
    4093     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    4094     */
    4095    public static int lastIndexOf(final int[] array, final int valueToFind) {
    4096        return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
    4097    }
    4098
    4099    /**
    4100     * Finds the last index of the given value in the array starting at the given index.
    4101     * <p>
    4102     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    4103     * </p>
    4104     * <p>
    4105     * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
    4106     * array length will search from the end of the array.
    4107     * </p>
    4108     *
    4109     * @param array  the array to traverse for looking for the object, may be {@code null}
    4110     * @param valueToFind  the value to find
    4111     * @param startIndex  the start index to traverse backwards from
    4112     * @return the last index of the value within the array,
    4113     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    4114     */
    4115    public static int lastIndexOf(final int[] array, final int valueToFind, int startIndex) {
    4116        if (array == null || startIndex < 0) {
    4117            return INDEX_NOT_FOUND;
    4118        }
    4119        if (startIndex >= array.length) {
    4120            startIndex = array.length - 1;
    4121        }
    4122        for (int i = startIndex; i >= 0; i--) {
    4123            if (valueToFind == array[i]) {
    4124                return i;
    4125            }
    4126        }
    4127        return INDEX_NOT_FOUND;
    4128    }
    4129
    4130    /**
    4131     * Finds the last index of the given value within the array.
    4132     * <p>
    4133     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    4134     * </p>
    4135     *
    4136     * @param array  the array to traverse backwards looking for the object, may be {@code null}
    4137     * @param valueToFind  the object to find
    4138     * @return the last index of the value within the array,
    4139     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    4140     */
    4141    public static int lastIndexOf(final long[] array, final long valueToFind) {
    4142        return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
    4143    }
    4144
    4145    /**
    4146     * Finds the last index of the given value in the array starting at the given index.
    4147     * <p>
    4148     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    4149     * </p>
    4150     * <p>
    4151     * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
    4152     * array length will search from the end of the array.
    4153     * </p>
    4154     *
    4155     * @param array  the array to traverse for looking for the object, may be {@code null}
    4156     * @param valueToFind  the value to find
    4157     * @param startIndex  the start index to traverse backwards from
    4158     * @return the last index of the value within the array,
    4159     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    4160     */
    4161    public static int lastIndexOf(final long[] array, final long valueToFind, int startIndex) {
    4162        if (array == null || startIndex < 0) {
    4163            return INDEX_NOT_FOUND;
    4164        }
    4165        if (startIndex >= array.length) {
    4166            startIndex = array.length - 1;
    4167        }
    4168        for (int i = startIndex; i >= 0; i--) {
    4169            if (valueToFind == array[i]) {
    4170                return i;
    4171            }
    4172        }
    4173        return INDEX_NOT_FOUND;
    4174    }
    4175
    4176    /**
    4177     * Finds the last index of the given object within the array.
    4178     * <p>
    4179     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    4180     * </p>
    4181     *
    4182     * @param array  the array to traverse backwards looking for the object, may be {@code null}
    4183     * @param objectToFind  the object to find, may be {@code null}
    4184     * @return the last index of the object within the array,
    4185     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    4186     */
    4187    public static int lastIndexOf(final Object[] array, final Object objectToFind) {
    4188        return lastIndexOf(array, objectToFind, Integer.MAX_VALUE);
    4189    }
    4190
    4191    /**
    4192     * Finds the last index of the given object in the array starting at the given index.
    4193     * <p>
    4194     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    4195     * </p>
    4196     * <p>
    4197     * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than
    4198     * the array length will search from the end of the array.
    4199     * </p>
    4200     *
    4201     * @param array  the array to traverse for looking for the object, may be {@code null}
    4202     * @param objectToFind  the object to find, may be {@code null}
    4203     * @param startIndex  the start index to traverse backwards from
    4204     * @return the last index of the object within the array,
    4205     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    4206     */
    4207    public static int lastIndexOf(final Object[] array, final Object objectToFind, int startIndex) {
    4208        if (array == null || startIndex < 0) {
    4209            return INDEX_NOT_FOUND;
    4210        }
    4211        if (startIndex >= array.length) {
    4212            startIndex = array.length - 1;
    4213        }
    4214        if (objectToFind == null) {
    4215            for (int i = startIndex; i >= 0; i--) {
    4216                if (array[i] == null) {
    4217                    return i;
    4218                }
    4219            }
    4220        } else if (array.getClass().getComponentType().isInstance(objectToFind)) {
    4221            for (int i = startIndex; i >= 0; i--) {
    4222                if (objectToFind.equals(array[i])) {
    4223                    return i;
    4224                }
    4225            }
    4226        }
    4227        return INDEX_NOT_FOUND;
    4228    }
    4229
    4230    /**
    4231     * Finds the last index of the given value within the array.
    4232     * <p>
    4233     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    4234     * </p>
    4235     *
    4236     * @param array  the array to traverse backwards looking for the object, may be {@code null}
    4237     * @param valueToFind  the object to find
    4238     * @return the last index of the value within the array,
    4239     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    4240     */
    4241    public static int lastIndexOf(final short[] array, final short valueToFind) {
    4242        return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
    4243    }
    4244
    4245    /**
    4246     * Finds the last index of the given value in the array starting at the given index.
    4247     * <p>
    4248     * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
    4249     * </p>
    4250     * <p>
    4251     * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
    4252     * array length will search from the end of the array.
    4253     * </p>
    4254     *
    4255     * @param array  the array to traverse for looking for the object, may be {@code null}
    4256     * @param valueToFind  the value to find
    4257     * @param startIndex  the start index to traverse backwards from
    4258     * @return the last index of the value within the array,
    4259     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
    4260     */
    4261    public static int lastIndexOf(final short[] array, final short valueToFind, int startIndex) {
    4262        if (array == null || startIndex < 0) {
    4263            return INDEX_NOT_FOUND;
    4264        }
    4265        if (startIndex >= array.length) {
    4266            startIndex = array.length - 1;
    4267        }
    4268        for (int i = startIndex; i >= 0; i--) {
    4269            if (valueToFind == array[i]) {
    4270                return i;
    4271            }
    4272        }
    4273        return INDEX_NOT_FOUND;
    4274    }
    4275
    4276    /**
    4277     * Delegates to {@link Array#newInstance(Class,int)} using generics.
    4278     *
    4279     * @param <T> The array type.
    4280     * @param componentType The array class.
    4281     * @param length the array length
    4282     * @return The new array.
    4283     * @throws NullPointerException if the specified {@code componentType} parameter is null.
    4284     * @since 3.13.0
    4285     */
    4286    @SuppressWarnings("unchecked") // OK, because array and values are of type T
    4287    public static <T> T[] newInstance(final Class<T> componentType, final int length) {
    4288        return (T[]) Array.newInstance(componentType, length);
    4289    }
    4290
    4291    /**
    4292     * Defensive programming technique to change a {@code null}
    4293     * reference to an empty one.
    4294     * <p>
    4295     * This method returns an empty array for a {@code null} input array.
    4296     * </p>
    4297     * <p>
    4298     * As a memory optimizing technique an empty array passed in will be overridden with
    4299     * the empty {@code public static} references in this class.
    4300     * </p>
    4301     *
    4302     * @param array  the array to check for {@code null} or empty
    4303     * @return the same array, {@code public static} empty array if {@code null} or empty input
    4304     * @since 2.5
    4305     */
    4306    public static boolean[] nullToEmpty(final boolean[] array) {
    4307        return isEmpty(array) ? EMPTY_BOOLEAN_ARRAY : array;
    4308    }
    4309
    4310    /**
    4311     * Defensive programming technique to change a {@code null}
    4312     * reference to an empty one.
    4313     * <p>
    4314     * This method returns an empty array for a {@code null} input array.
    4315     * </p>
    4316     * <p>
    4317     * As a memory optimizing technique an empty array passed in will be overridden with
    4318     * the empty {@code public static} references in this class.
    4319     * </p>
    4320     *
    4321     * @param array  the array to check for {@code null} or empty
    4322     * @return the same array, {@code public static} empty array if {@code null} or empty input
    4323     * @since 2.5
    4324     */
    4325    public static Boolean[] nullToEmpty(final Boolean[] array) {
    4326        return isEmpty(array) ? EMPTY_BOOLEAN_OBJECT_ARRAY : array;
    4327    }
    4328
    4329    /**
    4330     * Defensive programming technique to change a {@code null}
    4331     * reference to an empty one.
    4332     * <p>
    4333     * This method returns an empty array for a {@code null} input array.
    4334     * </p>
    4335     * <p>
    4336     * As a memory optimizing technique an empty array passed in will be overridden with
    4337     * the empty {@code public static} references in this class.
    4338     * </p>
    4339     *
    4340     * @param array  the array to check for {@code null} or empty
    4341     * @return the same array, {@code public static} empty array if {@code null} or empty input
    4342     * @since 2.5
    4343     */
    4344    public static byte[] nullToEmpty(final byte[] array) {
    4345        return isEmpty(array) ? EMPTY_BYTE_ARRAY : array;
    4346    }
    4347
    4348    /**
    4349     * Defensive programming technique to change a {@code null}
    4350     * reference to an empty one.
    4351     * <p>
    4352     * This method returns an empty array for a {@code null} input array.
    4353     * </p>
    4354     * <p>
    4355     * As a memory optimizing technique an empty array passed in will be overridden with
    4356     * the empty {@code public static} references in this class.
    4357     * </p>
    4358     *
    4359     * @param array  the array to check for {@code null} or empty
    4360     * @return the same array, {@code public static} empty array if {@code null} or empty input
    4361     * @since 2.5
    4362     */
    4363    public static Byte[] nullToEmpty(final Byte[] array) {
    4364        return isEmpty(array) ? EMPTY_BYTE_OBJECT_ARRAY : array;
    4365    }
    4366
    4367    /**
    4368     * Defensive programming technique to change a {@code null}
    4369     * reference to an empty one.
    4370     * <p>
    4371     * This method returns an empty array for a {@code null} input array.
    4372     * </p>
    4373     * <p>
    4374     * As a memory optimizing technique an empty array passed in will be overridden with
    4375     * the empty {@code public static} references in this class.
    4376     * </p>
    4377     *
    4378     * @param array  the array to check for {@code null} or empty
    4379     * @return the same array, {@code public static} empty array if {@code null} or empty input
    4380     * @since 2.5
    4381     */
    4382    public static char[] nullToEmpty(final char[] array) {
    4383        return isEmpty(array) ? EMPTY_CHAR_ARRAY : array;
    4384    }
    4385
    4386    /**
    4387     * Defensive programming technique to change a {@code null}
    4388     * reference to an empty one.
    4389     * <p>
    4390     * This method returns an empty array for a {@code null} input array.
    4391     * </p>
    4392     * <p>
    4393     * As a memory optimizing technique an empty array passed in will be overridden with
    4394     * the empty {@code public static} references in this class.
    4395     * </p>
    4396     *
    4397     * @param array  the array to check for {@code null} or empty
    4398     * @return the same array, {@code public static} empty array if {@code null} or empty input
    4399     * @since 2.5
    4400     */
    4401    public static Character[] nullToEmpty(final Character[] array) {
    4402        return isEmpty(array) ? EMPTY_CHARACTER_OBJECT_ARRAY : array;
    4403    }
    4404
    4405    /**
    4406     * Defensive programming technique to change a {@code null}
    4407     * reference to an empty one.
    4408     * <p>
    4409     * This method returns an empty array for a {@code null} input array.
    4410     * </p>
    4411     * <p>
    4412     * As a memory optimizing technique an empty array passed in will be overridden with
    4413     * the empty {@code public static} references in this class.
    4414     * </p>
    4415     *
    4416     * @param array  the array to check for {@code null} or empty
    4417     * @return the same array, {@code public static} empty array if {@code null} or empty input
    4418     * @since 3.2
    4419     */
    4420    public static Class<?>[] nullToEmpty(final Class<?>[] array) {
    4421        return isEmpty(array) ? EMPTY_CLASS_ARRAY : array;
    4422    }
    4423
    4424    /**
    4425     * Defensive programming technique to change a {@code null}
    4426     * reference to an empty one.
    4427     * <p>
    4428     * This method returns an empty array for a {@code null} input array.
    4429     * </p>
    4430     * <p>
    4431     * As a memory optimizing technique an empty array passed in will be overridden with
    4432     * the empty {@code public static} references in this class.
    4433     * </p>
    4434     *
    4435     * @param array  the array to check for {@code null} or empty
    4436     * @return the same array, {@code public static} empty array if {@code null} or empty input
    4437     * @since 2.5
    4438     */
    4439    public static double[] nullToEmpty(final double[] array) {
    4440        return isEmpty(array) ? EMPTY_DOUBLE_ARRAY : array;
    4441    }
    4442
    4443    /**
    4444     * Defensive programming technique to change a {@code null}
    4445     * reference to an empty one.
    4446     * <p>
    4447     * This method returns an empty array for a {@code null} input array.
    4448     * </p>
    4449     * <p>
    4450     * As a memory optimizing technique an empty array passed in will be overridden with
    4451     * the empty {@code public static} references in this class.
    4452     * </p>
    4453     *
    4454     * @param array  the array to check for {@code null} or empty
    4455     * @return the same array, {@code public static} empty array if {@code null} or empty input
    4456     * @since 2.5
    4457     */
    4458    public static Double[] nullToEmpty(final Double[] array) {
    4459        return isEmpty(array) ? EMPTY_DOUBLE_OBJECT_ARRAY : array;
    4460    }
    4461
    4462    /**
    4463     * Defensive programming technique to change a {@code null}
    4464     * reference to an empty one.
    4465     * <p>
    4466     * This method returns an empty array for a {@code null} input array.
    4467     * </p>
    4468     * <p>
    4469     * As a memory optimizing technique an empty array passed in will be overridden with
    4470     * the empty {@code public static} references in this class.
    4471     * </p>
    4472     *
    4473     * @param array  the array to check for {@code null} or empty
    4474     * @return the same array, {@code public static} empty array if {@code null} or empty input
    4475     * @since 2.5
    4476     */
    4477    public static float[] nullToEmpty(final float[] array) {
    4478        return isEmpty(array) ? EMPTY_FLOAT_ARRAY : array;
    4479    }
    4480
    4481    /**
    4482     * Defensive programming technique to change a {@code null}
    4483     * reference to an empty one.
    4484     * <p>
    4485     * This method returns an empty array for a {@code null} input array.
    4486     * </p>
    4487     * <p>
    4488     * As a memory optimizing technique an empty array passed in will be overridden with
    4489     * the empty {@code public static} references in this class.
    4490     * </p>
    4491     *
    4492     * @param array  the array to check for {@code null} or empty
    4493     * @return the same array, {@code public static} empty array if {@code null} or empty input
    4494     * @since 2.5
    4495     */
    4496    public static Float[] nullToEmpty(final Float[] array) {
    4497        return isEmpty(array) ? EMPTY_FLOAT_OBJECT_ARRAY : array;
    4498    }
    4499
    4500    /**
    4501     * Defensive programming technique to change a {@code null}
    4502     * reference to an empty one.
    4503     * <p>
    4504     * This method returns an empty array for a {@code null} input array.
    4505     * </p>
    4506     * <p>
    4507     * As a memory optimizing technique an empty array passed in will be overridden with
    4508     * the empty {@code public static} references in this class.
    4509     * </p>
    4510     *
    4511     * @param array  the array to check for {@code null} or empty
    4512     * @return the same array, {@code public static} empty array if {@code null} or empty input
    4513     * @since 2.5
    4514     */
    4515    public static int[] nullToEmpty(final int[] array) {
    4516        return isEmpty(array) ? EMPTY_INT_ARRAY : array;
    4517    }
    4518
    4519    /**
    4520     * Defensive programming technique to change a {@code null}
    4521     * reference to an empty one.
    4522     * <p>
    4523     * This method returns an empty array for a {@code null} input array.
    4524     * </p>
    4525     * <p>
    4526     * As a memory optimizing technique an empty array passed in will be overridden with
    4527     * the empty {@code public static} references in this class.
    4528     * </p>
    4529     *
    4530     * @param array  the array to check for {@code null} or empty
    4531     * @return the same array, {@code public static} empty array if {@code null} or empty input
    4532     * @since 2.5
    4533     */
    4534    public static Integer[] nullToEmpty(final Integer[] array) {
    4535        return isEmpty(array) ? EMPTY_INTEGER_OBJECT_ARRAY : array;
    4536    }
    4537
    4538    /**
    4539     * Defensive programming technique to change a {@code null}
    4540     * reference to an empty one.
    4541     * <p>
    4542     * This method returns an empty array for a {@code null} input array.
    4543     * </p>
    4544     * <p>
    4545     * As a memory optimizing technique an empty array passed in will be overridden with
    4546     * the empty {@code public static} references in this class.
    4547     * </p>
    4548     *
    4549     * @param array  the array to check for {@code null} or empty
    4550     * @return the same array, {@code public static} empty array if {@code null} or empty input
    4551     * @since 2.5
    4552     */
    4553    public static long[] nullToEmpty(final long[] array) {
    4554        return isEmpty(array) ? EMPTY_LONG_ARRAY : array;
    4555    }
    4556
    4557    /**
    4558     * Defensive programming technique to change a {@code null}
    4559     * reference to an empty one.
    4560     * <p>
    4561     * This method returns an empty array for a {@code null} input array.
    4562     * </p>
    4563     * <p>
    4564     * As a memory optimizing technique an empty array passed in will be overridden with
    4565     * the empty {@code public static} references in this class.
    4566     * </p>
    4567     *
    4568     * @param array  the array to check for {@code null} or empty
    4569     * @return the same array, {@code public static} empty array if {@code null} or empty input
    4570     * @since 2.5
    4571     */
    4572    public static Long[] nullToEmpty(final Long[] array) {
    4573        return isEmpty(array) ? EMPTY_LONG_OBJECT_ARRAY : array;
    4574    }
    4575
    4576    /**
    4577     * Defensive programming technique to change a {@code null}
    4578     * reference to an empty one.
    4579     * <p>
    4580     * This method returns an empty array for a {@code null} input array.
    4581     * </p>
    4582     * <p>
    4583     * As a memory optimizing technique an empty array passed in will be overridden with
    4584     * the empty {@code public static} references in this class.
    4585     * </p>
    4586     *
    4587     * @param array  the array to check for {@code null} or empty
    4588     * @return the same array, {@code public static} empty array if {@code null} or empty input
    4589     * @since 2.5
    4590     */
    4591    public static Object[] nullToEmpty(final Object[] array) {
    4592        return isEmpty(array) ? EMPTY_OBJECT_ARRAY : array;
    4593    }
    4594
    4595    /**
    4596     * Defensive programming technique to change a {@code null}
    4597     * reference to an empty one.
    4598     * <p>
    4599     * This method returns an empty array for a {@code null} input array.
    4600     * </p>
    4601     * <p>
    4602     * As a memory optimizing technique an empty array passed in will be overridden with
    4603     * the empty {@code public static} references in this class.
    4604     * </p>
    4605     *
    4606     * @param array  the array to check for {@code null} or empty
    4607     * @return the same array, {@code public static} empty array if {@code null} or empty input
    4608     * @since 2.5
    4609     */
    4610    public static short[] nullToEmpty(final short[] array) {
    4611        return isEmpty(array) ? EMPTY_SHORT_ARRAY : array;
    4612    }
    4613
    4614    /**
    4615     * Defensive programming technique to change a {@code null}
    4616     * reference to an empty one.
    4617     * <p>
    4618     * This method returns an empty array for a {@code null} input array.
    4619     * </p>
    4620     * <p>
    4621     * As a memory optimizing technique an empty array passed in will be overridden with
    4622     * the empty {@code public static} references in this class.
    4623     * </p>
    4624     *
    4625     * @param array  the array to check for {@code null} or empty
    4626     * @return the same array, {@code public static} empty array if {@code null} or empty input
    4627     * @since 2.5
    4628     */
    4629    public static Short[] nullToEmpty(final Short[] array) {
    4630        return isEmpty(array) ? EMPTY_SHORT_OBJECT_ARRAY : array;
    4631    }
    4632
    4633    /**
    4634     * Defensive programming technique to change a {@code null}
    4635     * reference to an empty one.
    4636     * <p>
    4637     * This method returns an empty array for a {@code null} input array.
    4638     * </p>
    4639     * <p>
    4640     * As a memory optimizing technique an empty array passed in will be overridden with
    4641     * the empty {@code public static} references in this class.
    4642     * </p>
    4643     *
    4644     * @param array  the array to check for {@code null} or empty
    4645     * @return the same array, {@code public static} empty array if {@code null} or empty input
    4646     * @since 2.5
    4647     */
    4648    public static String[] nullToEmpty(final String[] array) {
    4649        return isEmpty(array) ? EMPTY_STRING_ARRAY : array;
    4650    }
    4651
    4652    /**
    4653     * Defensive programming technique to change a {@code null}
    4654     * reference to an empty one.
    4655     * <p>
    4656     * This method returns an empty array for a {@code null} input array.
    4657     * </p>
    4658     *
    4659     * @param array  the array to check for {@code null} or empty
    4660     * @param type   the class representation of the desired array
    4661     * @param <T>  the class type
    4662     * @return the same array, {@code public static} empty array if {@code null}
    4663     * @throws IllegalArgumentException if the type argument is null
    4664     * @since 3.5
    4665     */
    4666    public static <T> T[] nullToEmpty(final T[] array, final Class<T[]> type) {
    4667        if (type == null) {
    4668            throw new IllegalArgumentException("The type must not be null");
    4669        }
    4670
    4671        if (array == null) {
    4672            return type.cast(Array.newInstance(type.getComponentType(), 0));
    4673        }
    4674        return array;
    4675    }
    4676
    4677    private static ThreadLocalRandom random() {
    4678        return ThreadLocalRandom.current();
    4679    }
    4680
    4681    /**
    4682     * Removes the element at the specified position from the specified array.
    4683     * All subsequent elements are shifted to the left (subtracts one from
    4684     * their indices).
    4685     * <p>
    4686     * This method returns a new array with the same elements of the input
    4687     * array except the element on the specified position. The component
    4688     * type of the returned array is always the same as that of the input
    4689     * array.
    4690     * </p>
    4691     * <p>
    4692     * If the input array is {@code null}, an IndexOutOfBoundsException
    4693     * will be thrown, because in that case no valid index can be specified.
    4694     * </p>
    4695     * <pre>
    4696     * ArrayUtils.remove([true], 0)              = []
    4697     * ArrayUtils.remove([true, false], 0)       = [false]
    4698     * ArrayUtils.remove([true, false], 1)       = [true]
    4699     * ArrayUtils.remove([true, true, false], 1) = [true, false]
    4700     * </pre>
    4701     *
    4702     * @param array  the array to remove the element from, may not be {@code null}
    4703     * @param index  the position of the element to be removed
    4704     * @return A new array containing the existing elements except the element
    4705     *         at the specified position.
    4706     * @throws IndexOutOfBoundsException if the index is out of range
    4707     * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
    4708     * @since 2.1
    4709     */
    4710    public static boolean[] remove(final boolean[] array, final int index) {
    4711        return (boolean[]) remove((Object) array, index);
    4712    }
    4713
    4714    /**
    4715     * Removes the element at the specified position from the specified array.
    4716     * All subsequent elements are shifted to the left (subtracts one from
    4717     * their indices).
    4718     * <p>
    4719     * This method returns a new array with the same elements of the input
    4720     * array except the element on the specified position. The component
    4721     * type of the returned array is always the same as that of the input
    4722     * array.
    4723     * </p>
    4724     * <p>
    4725     * If the input array is {@code null}, an IndexOutOfBoundsException
    4726     * will be thrown, because in that case no valid index can be specified.
    4727     * </p>
    4728     * <pre>
    4729     * ArrayUtils.remove([1], 0)          = []
    4730     * ArrayUtils.remove([1, 0], 0)       = [0]
    4731     * ArrayUtils.remove([1, 0], 1)       = [1]
    4732     * ArrayUtils.remove([1, 0, 1], 1)    = [1, 1]
    4733     * </pre>
    4734     *
    4735     * @param array  the array to remove the element from, may not be {@code null}
    4736     * @param index  the position of the element to be removed
    4737     * @return A new array containing the existing elements except the element
    4738     *         at the specified position.
    4739     * @throws IndexOutOfBoundsException if the index is out of range
    4740     * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
    4741     * @since 2.1
    4742     */
    4743    public static byte[] remove(final byte[] array, final int index) {
    4744        return (byte[]) remove((Object) array, index);
    4745    }
    4746
    4747    /**
    4748     * Removes the element at the specified position from the specified array.
    4749     * All subsequent elements are shifted to the left (subtracts one from
    4750     * their indices).
    4751     * <p>
    4752     * This method returns a new array with the same elements of the input
    4753     * array except the element on the specified position. The component
    4754     * type of the returned array is always the same as that of the input
    4755     * array.
    4756     * </p>
    4757     * <p>
    4758     * If the input array is {@code null}, an IndexOutOfBoundsException
    4759     * will be thrown, because in that case no valid index can be specified.
    4760     * </p>
    4761     * <pre>
    4762     * ArrayUtils.remove(['a'], 0)           = []
    4763     * ArrayUtils.remove(['a', 'b'], 0)      = ['b']
    4764     * ArrayUtils.remove(['a', 'b'], 1)      = ['a']
    4765     * ArrayUtils.remove(['a', 'b', 'c'], 1) = ['a', 'c']
    4766     * </pre>
    4767     *
    4768     * @param array  the array to remove the element from, may not be {@code null}
    4769     * @param index  the position of the element to be removed
    4770     * @return A new array containing the existing elements except the element
    4771     *         at the specified position.
    4772     * @throws IndexOutOfBoundsException if the index is out of range
    4773     * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
    4774     * @since 2.1
    4775     */
    4776    public static char[] remove(final char[] array, final int index) {
    4777        return (char[]) remove((Object) array, index);
    4778    }
    4779
    4780    /**
    4781     * Removes the element at the specified position from the specified array.
    4782     * All subsequent elements are shifted to the left (subtracts one from
    4783     * their indices).
    4784     * <p>
    4785     * This method returns a new array with the same elements of the input
    4786     * array except the element on the specified position. The component
    4787     * type of the returned array is always the same as that of the input
    4788     * array.
    4789     * </p>
    4790     * <p>
    4791     * If the input array is {@code null}, an IndexOutOfBoundsException
    4792     * will be thrown, because in that case no valid index can be specified.
    4793     * </p>
    4794     * <pre>
    4795     * ArrayUtils.remove([1.1], 0)           = []
    4796     * ArrayUtils.remove([2.5, 6.0], 0)      = [6.0]
    4797     * ArrayUtils.remove([2.5, 6.0], 1)      = [2.5]
    4798     * ArrayUtils.remove([2.5, 6.0, 3.8], 1) = [2.5, 3.8]
    4799     * </pre>
    4800     *
    4801     * @param array  the array to remove the element from, may not be {@code null}
    4802     * @param index  the position of the element to be removed
    4803     * @return A new array containing the existing elements except the element
    4804     *         at the specified position.
    4805     * @throws IndexOutOfBoundsException if the index is out of range
    4806     * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
    4807     * @since 2.1
    4808     */
    4809    public static double[] remove(final double[] array, final int index) {
    4810        return (double[]) remove((Object) array, index);
    4811    }
    4812
    4813    /**
    4814     * Removes the element at the specified position from the specified array.
    4815     * All subsequent elements are shifted to the left (subtracts one from
    4816     * their indices).
    4817     * <p>
    4818     * This method returns a new array with the same elements of the input
    4819     * array except the element on the specified position. The component
    4820     * type of the returned array is always the same as that of the input
    4821     * array.
    4822     * </p>
    4823     * <p>
    4824     * If the input array is {@code null}, an IndexOutOfBoundsException
    4825     * will be thrown, because in that case no valid index can be specified.
    4826     * </p>
    4827     * <pre>
    4828     * ArrayUtils.remove([1.1], 0)           = []
    4829     * ArrayUtils.remove([2.5, 6.0], 0)      = [6.0]
    4830     * ArrayUtils.remove([2.5, 6.0], 1)      = [2.5]
    4831     * ArrayUtils.remove([2.5, 6.0, 3.8], 1) = [2.5, 3.8]
    4832     * </pre>
    4833     *
    4834     * @param array  the array to remove the element from, may not be {@code null}
    4835     * @param index  the position of the element to be removed
    4836     * @return A new array containing the existing elements except the element
    4837     *         at the specified position.
    4838     * @throws IndexOutOfBoundsException if the index is out of range
    4839     * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
    4840     * @since 2.1
    4841     */
    4842    public static float[] remove(final float[] array, final int index) {
    4843        return (float[]) remove((Object) array, index);
    4844    }
    4845
    4846    /**
    4847     * Removes the element at the specified position from the specified array.
    4848     * All subsequent elements are shifted to the left (subtracts one from
    4849     * their indices).
    4850     * <p>
    4851     * This method returns a new array with the same elements of the input
    4852     * array except the element on the specified position. The component
    4853     * type of the returned array is always the same as that of the input
    4854     * array.
    4855     * </p>
    4856     * <p>
    4857     * If the input array is {@code null}, an IndexOutOfBoundsException
    4858     * will be thrown, because in that case no valid index can be specified.
    4859     * </p>
    4860     * <pre>
    4861     * ArrayUtils.remove([1], 0)         = []
    4862     * ArrayUtils.remove([2, 6], 0)      = [6]
    4863     * ArrayUtils.remove([2, 6], 1)      = [2]
    4864     * ArrayUtils.remove([2, 6, 3], 1)   = [2, 3]
    4865     * </pre>
    4866     *
    4867     * @param array  the array to remove the element from, may not be {@code null}
    4868     * @param index  the position of the element to be removed
    4869     * @return A new array containing the existing elements except the element
    4870     *         at the specified position.
    4871     * @throws IndexOutOfBoundsException if the index is out of range
    4872     * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
    4873     * @since 2.1
    4874     */
    4875    public static int[] remove(final int[] array, final int index) {
    4876        return (int[]) remove((Object) array, index);
    4877    }
    4878
    4879    /**
    4880     * Removes the element at the specified position from the specified array.
    4881     * All subsequent elements are shifted to the left (subtracts one from
    4882     * their indices).
    4883     * <p>
    4884     * This method returns a new array with the same elements of the input
    4885     * array except the element on the specified position. The component
    4886     * type of the returned array is always the same as that of the input
    4887     * array.
    4888     * </p>
    4889     * <p>
    4890     * If the input array is {@code null}, an IndexOutOfBoundsException
    4891     * will be thrown, because in that case no valid index can be specified.
    4892     * </p>
    4893     * <pre>
    4894     * ArrayUtils.remove([1], 0)         = []
    4895     * ArrayUtils.remove([2, 6], 0)      = [6]
    4896     * ArrayUtils.remove([2, 6], 1)      = [2]
    4897     * ArrayUtils.remove([2, 6, 3], 1)   = [2, 3]
    4898     * </pre>
    4899     *
    4900     * @param array  the array to remove the element from, may not be {@code null}
    4901     * @param index  the position of the element to be removed
    4902     * @return A new array containing the existing elements except the element
    4903     *         at the specified position.
    4904     * @throws IndexOutOfBoundsException if the index is out of range
    4905     * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
    4906     * @since 2.1
    4907     */
    4908    public static long[] remove(final long[] array, final int index) {
    4909        return (long[]) remove((Object) array, index);
    4910    }
    4911
    4912    /**
    4913     * Removes the element at the specified position from the specified array.
    4914     * All subsequent elements are shifted to the left (subtracts one from
    4915     * their indices).
    4916     * <p>
    4917     * This method returns a new array with the same elements of the input
    4918     * array except the element on the specified position. The component
    4919     * type of the returned array is always the same as that of the input
    4920     * array.
    4921     * </p>
    4922     * <p>
    4923     * If the input array is {@code null}, an IndexOutOfBoundsException
    4924     * will be thrown, because in that case no valid index can be specified.
    4925     * </p>
    4926     *
    4927     * @param array  the array to remove the element from, may not be {@code null}
    4928     * @param index  the position of the element to be removed
    4929     * @return A new array containing the existing elements except the element
    4930     *         at the specified position.
    4931     * @throws IndexOutOfBoundsException if the index is out of range
    4932     * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
    4933     * @since 2.1
    4934     */
    4935    private static Object remove(final Object array, final int index) {
    4936        final int length = getLength(array);
    4937        if (index < 0 || index >= length) {
    4938            throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + length);
    4939        }
    4940
    4941        final Object result = Array.newInstance(array.getClass().getComponentType(), length - 1);
    4942        System.arraycopy(array, 0, result, 0, index);
    4943        if (index < length - 1) {
    4944            System.arraycopy(array, index + 1, result, index, length - index - 1);
    4945        }
    4946
    4947        return result;
    4948    }
    4949
    4950    /**
    4951     * Removes the element at the specified position from the specified array.
    4952     * All subsequent elements are shifted to the left (subtracts one from
    4953     * their indices).
    4954     * <p>
    4955     * This method returns a new array with the same elements of the input
    4956     * array except the element on the specified position. The component
    4957     * type of the returned array is always the same as that of the input
    4958     * array.
    4959     * </p>
    4960     * <p>
    4961     * If the input array is {@code null}, an IndexOutOfBoundsException
    4962     * will be thrown, because in that case no valid index can be specified.
    4963     * </p>
    4964     * <pre>
    4965     * ArrayUtils.remove([1], 0)         = []
    4966     * ArrayUtils.remove([2, 6], 0)      = [6]
    4967     * ArrayUtils.remove([2, 6], 1)      = [2]
    4968     * ArrayUtils.remove([2, 6, 3], 1)   = [2, 3]
    4969     * </pre>
    4970     *
    4971     * @param array  the array to remove the element from, may not be {@code null}
    4972     * @param index  the position of the element to be removed
    4973     * @return A new array containing the existing elements except the element
    4974     *         at the specified position.
    4975     * @throws IndexOutOfBoundsException if the index is out of range
    4976     * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
    4977     * @since 2.1
    4978     */
    4979    public static short[] remove(final short[] array, final int index) {
    4980        return (short[]) remove((Object) array, index);
    4981    }
    4982
    4983    /**
    4984     * Removes the element at the specified position from the specified array.
    4985     * All subsequent elements are shifted to the left (subtracts one from
    4986     * their indices).
    4987     * <p>
    4988     * This method returns a new array with the same elements of the input
    4989     * array except the element on the specified position. The component
    4990     * type of the returned array is always the same as that of the input
    4991     * array.
    4992     * </p>
    4993     * <p>
    4994     * If the input array is {@code null}, an IndexOutOfBoundsException
    4995     * will be thrown, because in that case no valid index can be specified.
    4996     * </p>
    4997     * <pre>
    4998     * ArrayUtils.remove(["a"], 0)           = []
    4999     * ArrayUtils.remove(["a", "b"], 0)      = ["b"]
    5000     * ArrayUtils.remove(["a", "b"], 1)      = ["a"]
    5001     * ArrayUtils.remove(["a", "b", "c"], 1) = ["a", "c"]
    5002     * </pre>
    5003     *
    5004     * @param <T> the component type of the array
    5005     * @param array  the array to remove the element from, may not be {@code null}
    5006     * @param index  the position of the element to be removed
    5007     * @return A new array containing the existing elements except the element
    5008     *         at the specified position.
    5009     * @throws IndexOutOfBoundsException if the index is out of range
    5010     * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
    5011     * @since 2.1
    5012     */
    5013    @SuppressWarnings("unchecked") // remove() always creates an array of the same type as its input
    5014    public static <T> T[] remove(final T[] array, final int index) {
    5015        return (T[]) remove((Object) array, index);
    5016    }
    5017
    5018    /**
    5019     * Removes the elements at the specified positions from the specified array.
    5020     * All remaining elements are shifted to the left.
    5021     * <p>
    5022     * This method returns a new array with the same elements of the input
    5023     * array except those at the specified positions. The component
    5024     * type of the returned array is always the same as that of the input
    5025     * array.
    5026     * </p>
    5027     * <p>
    5028     * If the input array is {@code null}, an IndexOutOfBoundsException
    5029     * will be thrown, because in that case no valid index can be specified.
    5030     * </p>
    5031     * <pre>
    5032     * ArrayUtils.removeAll([true, false, true], 0, 2) = [false]
    5033     * ArrayUtils.removeAll([true, false, true], 1, 2) = [true]
    5034     * </pre>
    5035     *
    5036     * @param array   the array to remove the element from, may not be {@code null}
    5037     * @param indices the positions of the elements to be removed
    5038     * @return A new array containing the existing elements except those
    5039     *         at the specified positions.
    5040     * @throws IndexOutOfBoundsException if any index is out of range
    5041     * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
    5042     * @since 3.0.1
    5043     */
    5044    public static boolean[] removeAll(final boolean[] array, final int... indices) {
    5045        return (boolean[]) removeAll((Object) array, indices);
    5046    }
    5047
    5048    /**
    5049     * Removes the elements at the specified positions from the specified array.
    5050     * All remaining elements are shifted to the left.
    5051     * <p>
    5052     * This method returns a new array with the same elements of the input
    5053     * array except those at the specified positions. The component
    5054     * type of the returned array is always the same as that of the input
    5055     * array.
    5056     * </p>
    5057     * <p>
    5058     * If the input array is {@code null}, an IndexOutOfBoundsException
    5059     * will be thrown, because in that case no valid index can be specified.
    5060     * </p>
    5061     * <pre>
    5062     * ArrayUtils.removeAll([1], 0)             = []
    5063     * ArrayUtils.removeAll([2, 6], 0)          = [6]
    5064     * ArrayUtils.removeAll([2, 6], 0, 1)       = []
    5065     * ArrayUtils.removeAll([2, 6, 3], 1, 2)    = [2]
    5066     * ArrayUtils.removeAll([2, 6, 3], 0, 2)    = [6]
    5067     * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
    5068     * </pre>
    5069     *
    5070     * @param array   the array to remove the element from, may not be {@code null}
    5071     * @param indices the positions of the elements to be removed
    5072     * @return A new array containing the existing elements except those
    5073     *         at the specified positions.
    5074     * @throws IndexOutOfBoundsException if any index is out of range
    5075     * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
    5076     * @since 3.0.1
    5077     */
    5078    public static byte[] removeAll(final byte[] array, final int... indices) {
    5079        return (byte[]) removeAll((Object) array, indices);
    5080    }
    5081
    5082    /**
    5083     * Removes the elements at the specified positions from the specified array.
    5084     * All remaining elements are shifted to the left.
    5085     * <p>
    5086     * This method returns a new array with the same elements of the input
    5087     * array except those at the specified positions. The component
    5088     * type of the returned array is always the same as that of the input
    5089     * array.
    5090     * </p>
    5091     * <p>
    5092     * If the input array is {@code null}, an IndexOutOfBoundsException
    5093     * will be thrown, because in that case no valid index can be specified.
    5094     * </p>
    5095     * <pre>
    5096     * ArrayUtils.removeAll([1], 0)             = []
    5097     * ArrayUtils.removeAll([2, 6], 0)          = [6]
    5098     * ArrayUtils.removeAll([2, 6], 0, 1)       = []
    5099     * ArrayUtils.removeAll([2, 6, 3], 1, 2)    = [2]
    5100     * ArrayUtils.removeAll([2, 6, 3], 0, 2)    = [6]
    5101     * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
    5102     * </pre>
    5103     *
    5104     * @param array   the array to remove the element from, may not be {@code null}
    5105     * @param indices the positions of the elements to be removed
    5106     * @return A new array containing the existing elements except those
    5107     *         at the specified positions.
    5108     * @throws IndexOutOfBoundsException if any index is out of range
    5109     * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
    5110     * @since 3.0.1
    5111     */
    5112    public static char[] removeAll(final char[] array, final int... indices) {
    5113        return (char[]) removeAll((Object) array, indices);
    5114    }
    5115
    5116    /**
    5117     * Removes the elements at the specified positions from the specified array.
    5118     * All remaining elements are shifted to the left.
    5119     * <p>
    5120     * This method returns a new array with the same elements of the input
    5121     * array except those at the specified positions. The component
    5122     * type of the returned array is always the same as that of the input
    5123     * array.
    5124     * </p>
    5125     * <p>
    5126     * If the input array is {@code null}, an IndexOutOfBoundsException
    5127     * will be thrown, because in that case no valid index can be specified.
    5128     * </p>
    5129     * <pre>
    5130     * ArrayUtils.removeAll([1], 0)             = []
    5131     * ArrayUtils.removeAll([2, 6], 0)          = [6]
    5132     * ArrayUtils.removeAll([2, 6], 0, 1)       = []
    5133     * ArrayUtils.removeAll([2, 6, 3], 1, 2)    = [2]
    5134     * ArrayUtils.removeAll([2, 6, 3], 0, 2)    = [6]
    5135     * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
    5136     * </pre>
    5137     *
    5138     * @param array   the array to remove the element from, may not be {@code null}
    5139     * @param indices the positions of the elements to be removed
    5140     * @return A new array containing the existing elements except those
    5141     *         at the specified positions.
    5142     * @throws IndexOutOfBoundsException if any index is out of range
    5143     * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
    5144     * @since 3.0.1
    5145     */
    5146    public static double[] removeAll(final double[] array, final int... indices) {
    5147        return (double[]) removeAll((Object) array, indices);
    5148    }
    5149
    5150    /**
    5151     * Removes the elements at the specified positions from the specified array.
    5152     * All remaining elements are shifted to the left.
    5153     * <p>
    5154     * This method returns a new array with the same elements of the input
    5155     * array except those at the specified positions. The component
    5156     * type of the returned array is always the same as that of the input
    5157     * array.
    5158     * </p>
    5159     * <p>
    5160     * If the input array is {@code null}, an IndexOutOfBoundsException
    5161     * will be thrown, because in that case no valid index can be specified.
    5162     * </p>
    5163     * <pre>
    5164     * ArrayUtils.removeAll([1], 0)             = []
    5165     * ArrayUtils.removeAll([2, 6], 0)          = [6]
    5166     * ArrayUtils.removeAll([2, 6], 0, 1)       = []
    5167     * ArrayUtils.removeAll([2, 6, 3], 1, 2)    = [2]
    5168     * ArrayUtils.removeAll([2, 6, 3], 0, 2)    = [6]
    5169     * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
    5170     * </pre>
    5171     *
    5172     * @param array   the array to remove the element from, may not be {@code null}
    5173     * @param indices the positions of the elements to be removed
    5174     * @return A new array containing the existing elements except those
    5175     *         at the specified positions.
    5176     * @throws IndexOutOfBoundsException if any index is out of range
    5177     * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
    5178     * @since 3.0.1
    5179     */
    5180    public static float[] removeAll(final float[] array, final int... indices) {
    5181        return (float[]) removeAll((Object) array, indices);
    5182    }
    5183
    5184    /**
    5185     * Removes the elements at the specified positions from the specified array.
    5186     * All remaining elements are shifted to the left.
    5187     * <p>
    5188     * This method returns a new array with the same elements of the input
    5189     * array except those at the specified positions. The component
    5190     * type of the returned array is always the same as that of the input
    5191     * array.
    5192     * </p>
    5193     * <p>
    5194     * If the input array is {@code null}, an IndexOutOfBoundsException
    5195     * will be thrown, because in that case no valid index can be specified.
    5196     * </p>
    5197     * <pre>
    5198     * ArrayUtils.removeAll([1], 0)             = []
    5199     * ArrayUtils.removeAll([2, 6], 0)          = [6]
    5200     * ArrayUtils.removeAll([2, 6], 0, 1)       = []
    5201     * ArrayUtils.removeAll([2, 6, 3], 1, 2)    = [2]
    5202     * ArrayUtils.removeAll([2, 6, 3], 0, 2)    = [6]
    5203     * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
    5204     * </pre>
    5205     *
    5206     * @param array   the array to remove the element from, may not be {@code null}
    5207     * @param indices the positions of the elements to be removed
    5208     * @return A new array containing the existing elements except those
    5209     *         at the specified positions.
    5210     * @throws IndexOutOfBoundsException if any index is out of range
    5211     * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
    5212     * @since 3.0.1
    5213     */
    5214    public static int[] removeAll(final int[] array, final int... indices) {
    5215        return (int[]) removeAll((Object) array, indices);
    5216    }
    5217
    5218    /**
    5219     * Removes the elements at the specified positions from the specified array.
    5220     * All remaining elements are shifted to the left.
    5221     * <p>
    5222     * This method returns a new array with the same elements of the input
    5223     * array except those at the specified positions. The component
    5224     * type of the returned array is always the same as that of the input
    5225     * array.
    5226     * </p>
    5227     * <p>
    5228     * If the input array is {@code null}, an IndexOutOfBoundsException
    5229     * will be thrown, because in that case no valid index can be specified.
    5230     * </p>
    5231     * <pre>
    5232     * ArrayUtils.removeAll([1], 0)             = []
    5233     * ArrayUtils.removeAll([2, 6], 0)          = [6]
    5234     * ArrayUtils.removeAll([2, 6], 0, 1)       = []
    5235     * ArrayUtils.removeAll([2, 6, 3], 1, 2)    = [2]
    5236     * ArrayUtils.removeAll([2, 6, 3], 0, 2)    = [6]
    5237     * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
    5238     * </pre>
    5239     *
    5240     * @param array   the array to remove the element from, may not be {@code null}
    5241     * @param indices the positions of the elements to be removed
    5242     * @return A new array containing the existing elements except those
    5243     *         at the specified positions.
    5244     * @throws IndexOutOfBoundsException if any index is out of range
    5245     * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
    5246     * @since 3.0.1
    5247     */
    5248    public static long[] removeAll(final long[] array, final int... indices) {
    5249        return (long[]) removeAll((Object) array, indices);
    5250    }
    5251
    5252    /**
    5253     * Removes multiple array elements specified by indices.
    5254     *
    5255     * @param array source
    5256     * @param indices to remove
    5257     * @return new array of same type minus elements specified by the set bits in {@code indices}
    5258     * @since 3.2
    5259     */
    5260    // package protected for access by unit tests
    5261    static Object removeAll(final Object array, final BitSet indices) {
    5262        if (array == null) {
    5263            return null;
    5264        }
    5265
    5266        final int srcLength = getLength(array);
    5267        // No need to check maxIndex here, because method only currently called from removeElements()
    5268        // which guarantee to generate only valid bit entries.
    5269//        final int maxIndex = indices.length();
    5270//        if (maxIndex > srcLength) {
    5271//            throw new IndexOutOfBoundsException("Index: " + (maxIndex-1) + ", Length: " + srcLength);
    5272//        }
    5273        final int removals = indices.cardinality(); // true bits are items to remove
    5274        final Object result = Array.newInstance(array.getClass().getComponentType(), srcLength - removals);
    5275        int srcIndex = 0;
    5276        int destIndex = 0;
    5277        int count;
    5278        int set;
    5279        while ((set = indices.nextSetBit(srcIndex)) != -1) {
    5280            count = set - srcIndex;
    5281            if (count > 0) {
    5282                System.arraycopy(array, srcIndex, result, destIndex, count);
    5283                destIndex += count;
    5284            }
    5285            srcIndex = indices.nextClearBit(set);
    5286        }
    5287        count = srcLength - srcIndex;
    5288        if (count > 0) {
    5289            System.arraycopy(array, srcIndex, result, destIndex, count);
    5290        }
    5291        return result;
    5292    }
    5293
    5294    /**
    5295     * Removes multiple array elements specified by index.
    5296     *
    5297     * @param array source
    5298     * @param indices to remove
    5299     * @return new array of same type minus elements specified by unique values of {@code indices}
    5300     * @since 3.0.1
    5301     */
    5302    // package protected for access by unit tests
    5303    static Object removeAll(final Object array, final int... indices) {
    5304        final int length = getLength(array);
    5305        int diff = 0; // number of distinct indexes, i.e. number of entries that will be removed
    5306        final int[] clonedIndices = ArraySorter.sort(clone(indices));
    5307
    5308        // identify length of result array
    5309        if (isNotEmpty(clonedIndices)) {
    5310            int i = clonedIndices.length;
    5311            int prevIndex = length;
    5312            while (--i >= 0) {
    5313                final int index = clonedIndices[i];
    5314                if (index < 0 || index >= length) {
    5315                    throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + length);
    5316                }
    5317                if (index >= prevIndex) {
    5318                    continue;
    5319                }
    5320                diff++;
    5321                prevIndex = index;
    5322            }
    5323        }
    5324
    5325        // create result array
    5326        final Object result = Array.newInstance(array.getClass().getComponentType(), length - diff);
    5327        if (diff < length) {
    5328            int end = length; // index just after last copy
    5329            int dest = length - diff; // number of entries so far not copied
    5330            for (int i = clonedIndices.length - 1; i >= 0; i--) {
    5331                final int index = clonedIndices[i];
    5332                if (end - index > 1) { // same as (cp > 0)
    5333                    final int cp = end - index - 1;
    5334                    dest -= cp;
    5335                    System.arraycopy(array, index + 1, result, dest, cp);
    5336                    // After this copy, we still have room for dest items.
    5337                }
    5338                end = index;
    5339            }
    5340            if (end > 0) {
    5341                System.arraycopy(array, 0, result, 0, end);
    5342            }
    5343        }
    5344        return result;
    5345    }
    5346
    5347    /**
    5348     * Removes the elements at the specified positions from the specified array.
    5349     * All remaining elements are shifted to the left.
    5350     * <p>
    5351     * This method returns a new array with the same elements of the input
    5352     * array except those at the specified positions. The component
    5353     * type of the returned array is always the same as that of the input
    5354     * array.
    5355     * </p>
    5356     * <p>
    5357     * If the input array is {@code null}, an IndexOutOfBoundsException
    5358     * will be thrown, because in that case no valid index can be specified.
    5359     * </p>
    5360     * <pre>
    5361     * ArrayUtils.removeAll([1], 0)             = []
    5362     * ArrayUtils.removeAll([2, 6], 0)          = [6]
    5363     * ArrayUtils.removeAll([2, 6], 0, 1)       = []
    5364     * ArrayUtils.removeAll([2, 6, 3], 1, 2)    = [2]
    5365     * ArrayUtils.removeAll([2, 6, 3], 0, 2)    = [6]
    5366     * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
    5367     * </pre>
    5368     *
    5369     * @param array   the array to remove the element from, may not be {@code null}
    5370     * @param indices the positions of the elements to be removed
    5371     * @return A new array containing the existing elements except those
    5372     *         at the specified positions.
    5373     * @throws IndexOutOfBoundsException if any index is out of range
    5374     * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
    5375     * @since 3.0.1
    5376     */
    5377    public static short[] removeAll(final short[] array, final int... indices) {
    5378        return (short[]) removeAll((Object) array, indices);
    5379    }
    5380
    5381    /**
    5382     * Removes the elements at the specified positions from the specified array.
    5383     * All remaining elements are shifted to the left.
    5384     * <p>
    5385     * This method returns a new array with the same elements of the input
    5386     * array except those at the specified positions. The component
    5387     * type of the returned array is always the same as that of the input
    5388     * array.
    5389     * </p>
    5390     * <p>
    5391     * If the input array is {@code null}, an IndexOutOfBoundsException
    5392     * will be thrown, because in that case no valid index can be specified.
    5393     * </p>
    5394     * <pre>
    5395     * ArrayUtils.removeAll(["a", "b", "c"], 0, 2) = ["b"]
    5396     * ArrayUtils.removeAll(["a", "b", "c"], 1, 2) = ["a"]
    5397     * </pre>
    5398     *
    5399     * @param <T> the component type of the array
    5400     * @param array   the array to remove the element from, may not be {@code null}
    5401     * @param indices the positions of the elements to be removed
    5402     * @return A new array containing the existing elements except those
    5403     *         at the specified positions.
    5404     * @throws IndexOutOfBoundsException if any index is out of range
    5405     * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
    5406     * @since 3.0.1
    5407     */
    5408    @SuppressWarnings("unchecked") // removeAll() always creates an array of the same type as its input
    5409    public static <T> T[] removeAll(final T[] array, final int... indices) {
    5410        return (T[]) removeAll((Object) array, indices);
    5411    }
    5412
    5413    /**
    5414     * Removes the occurrences of the specified element from the specified boolean array.
    5415     * <p>
    5416     * All subsequent elements are shifted to the left (subtracts one from their indices).
    5417     * If the array doesn't contain such an element, no elements are removed from the array.
    5418     * {@code null} will be returned if the input array is {@code null}.
    5419     * </p>
    5420     *
    5421     * @param element the element to remove
    5422     * @param array the input array
    5423     *
    5424     * @return A new array containing the existing elements except the occurrences of the specified element.
    5425     * @since 3.5
    5426     * @deprecated Use {@link #removeAllOccurrences(boolean[], boolean)}
    5427     */
    5428    @Deprecated
    5429    public static boolean[] removeAllOccurences(final boolean[] array, final boolean element) {
    5430        return (boolean[]) removeAll((Object) array, indexesOf(array, element));
    5431    }
    5432
    5433    /**
    5434     * Removes the occurrences of the specified element from the specified byte array.
    5435     * <p>
    5436     * All subsequent elements are shifted to the left (subtracts one from their indices).
    5437     * If the array doesn't contain such an element, no elements are removed from the array.
    5438     * {@code null} will be returned if the input array is {@code null}.
    5439     * </p>
    5440     *
    5441     * @param element the element to remove
    5442     * @param array the input array
    5443     *
    5444     * @return A new array containing the existing elements except the occurrences of the specified element.
    5445     * @since 3.5
    5446     * @deprecated Use {@link #removeAllOccurrences(byte[], byte)}
    5447     */
    5448    @Deprecated
    5449    public static byte[] removeAllOccurences(final byte[] array, final byte element) {
    5450        return (byte[]) removeAll((Object) array, indexesOf(array, element));
    5451    }
    5452
    5453    /**
    5454     * Removes the occurrences of the specified element from the specified char array.
    5455     * <p>
    5456     * All subsequent elements are shifted to the left (subtracts one from their indices).
    5457     * If the array doesn't contain such an element, no elements are removed from the array.
    5458     * {@code null} will be returned if the input array is {@code null}.
    5459     * </p>
    5460     *
    5461     * @param element the element to remove
    5462     * @param array the input array
    5463     *
    5464     * @return A new array containing the existing elements except the occurrences of the specified element.
    5465     * @since 3.5
    5466     * @deprecated Use {@link #removeAllOccurrences(char[], char)}
    5467     */
    5468    @Deprecated
    5469    public static char[] removeAllOccurences(final char[] array, final char element) {
    5470        return (char[]) removeAll((Object) array, indexesOf(array, element));
    5471    }
    5472
    5473    /**
    5474     * Removes the occurrences of the specified element from the specified double array.
    5475     * <p>
    5476     * All subsequent elements are shifted to the left (subtracts one from their indices).
    5477     * If the array doesn't contain such an element, no elements are removed from the array.
    5478     * {@code null} will be returned if the input array is {@code null}.
    5479     * </p>
    5480     *
    5481     * @param element the element to remove
    5482     * @param array the input array
    5483     *
    5484     * @return A new array containing the existing elements except the occurrences of the specified element.
    5485     * @since 3.5
    5486     * @deprecated Use {@link #removeAllOccurrences(double[], double)}
    5487     */
    5488    @Deprecated
    5489    public static double[] removeAllOccurences(final double[] array, final double element) {
    5490        return (double[]) removeAll((Object) array, indexesOf(array, element));
    5491    }
    5492
    5493    /**
    5494     * Removes the occurrences of the specified element from the specified float array.
    5495     * <p>
    5496     * All subsequent elements are shifted to the left (subtracts one from their indices).
    5497     * If the array doesn't contain such an element, no elements are removed from the array.
    5498     * {@code null} will be returned if the input array is {@code null}.
    5499     * </p>
    5500     *
    5501     * @param element the element to remove
    5502     * @param array the input array
    5503     *
    5504     * @return A new array containing the existing elements except the occurrences of the specified element.
    5505     * @since 3.5
    5506     * @deprecated Use {@link #removeAllOccurrences(float[], float)}
    5507     */
    5508    @Deprecated
    5509    public static float[] removeAllOccurences(final float[] array, final float element) {
    5510        return (float[]) removeAll((Object) array, indexesOf(array, element));
    5511    }
    5512
    5513    /**
    5514     * Removes the occurrences of the specified element from the specified int array.
    5515     * <p>
    5516     * All subsequent elements are shifted to the left (subtracts one from their indices).
    5517     * If the array doesn't contain such an element, no elements are removed from the array.
    5518     * {@code null} will be returned if the input array is {@code null}.
    5519     * </p>
    5520     *
    5521     * @param element the element to remove
    5522     * @param array the input array
    5523     *
    5524     * @return A new array containing the existing elements except the occurrences of the specified element.
    5525     * @since 3.5
    5526     * @deprecated Use {@link #removeAllOccurrences(int[], int)}
    5527     */
    5528    @Deprecated
    5529    public static int[] removeAllOccurences(final int[] array, final int element) {
    5530        return (int[]) removeAll((Object) array, indexesOf(array, element));
    5531    }
    5532
    5533    /**
    5534     * Removes the occurrences of the specified element from the specified long array.
    5535     * <p>
    5536     * All subsequent elements are shifted to the left (subtracts one from their indices).
    5537     * If the array doesn't contain such an element, no elements are removed from the array.
    5538     * {@code null} will be returned if the input array is {@code null}.
    5539     * </p>
    5540     *
    5541     * @param element the element to remove
    5542     * @param array the input array
    5543     *
    5544     * @return A new array containing the existing elements except the occurrences of the specified element.
    5545     * @since 3.5
    5546     * @deprecated Use {@link #removeAllOccurrences(long[], long)}
    5547     */
    5548    @Deprecated
    5549    public static long[] removeAllOccurences(final long[] array, final long element) {
    5550        return (long[]) removeAll((Object) array, indexesOf(array, element));
    5551    }
    5552
    5553    /**
    5554     * Removes the occurrences of the specified element from the specified short array.
    5555     * <p>
    5556     * All subsequent elements are shifted to the left (subtracts one from their indices).
    5557     * If the array doesn't contain such an element, no elements are removed from the array.
    5558     * {@code null} will be returned if the input array is {@code null}.
    5559     * </p>
    5560     *
    5561     * @param element the element to remove
    5562     * @param array the input array
    5563     *
    5564     * @return A new array containing the existing elements except the occurrences of the specified element.
    5565     * @since 3.5
    5566     * @deprecated Use {@link #removeAllOccurrences(short[], short)}
    5567     */
    5568    @Deprecated
    5569    public static short[] removeAllOccurences(final short[] array, final short element) {
    5570        return (short[]) removeAll((Object) array, indexesOf(array, element));
    5571    }
    5572
    5573    /**
    5574     * Removes the occurrences of the specified element from the specified array.
    5575     * <p>
    5576     * All subsequent elements are shifted to the left (subtracts one from their indices).
    5577     * If the array doesn't contain such an element, no elements are removed from the array.
    5578     * {@code null} will be returned if the input array is {@code null}.
    5579     * </p>
    5580     *
    5581     * @param <T> the type of object in the array
    5582     * @param element the element to remove
    5583     * @param array the input array
    5584     *
    5585     * @return A new array containing the existing elements except the occurrences of the specified element.
    5586     * @since 3.5
    5587     * @deprecated Use {@link #removeAllOccurrences(Object[], Object)}
    5588     */
    5589    @Deprecated
    5590    public static <T> T[] removeAllOccurences(final T[] array, final T element) {
    5591        return (T[]) removeAll((Object) array, indexesOf(array, element));
    5592    }
    5593
    5594    /**
    5595     * Removes the occurrences of the specified element from the specified boolean array.
    5596     * <p>
    5597     * All subsequent elements are shifted to the left (subtracts one from their indices).
    5598     * If the array doesn't contain such an element, no elements are removed from the array.
    5599     * {@code null} will be returned if the input array is {@code null}.
    5600     * </p>
    5601     *
    5602     * @param element the element to remove
    5603     * @param array the input array
    5604     *
    5605     * @return A new array containing the existing elements except the occurrences of the specified element.
    5606     * @since 3.10
    5607     */
    5608    public static boolean[] removeAllOccurrences(final boolean[] array, final boolean element) {
    5609        return (boolean[]) removeAll((Object) array, indexesOf(array, element));
    5610    }
    5611
    5612    /**
    5613     * Removes the occurrences of the specified element from the specified byte array.
    5614     * <p>
    5615     * All subsequent elements are shifted to the left (subtracts one from their indices).
    5616     * If the array doesn't contain such an element, no elements are removed from the array.
    5617     * {@code null} will be returned if the input array is {@code null}.
    5618     * </p>
    5619     *
    5620     * @param element the element to remove
    5621     * @param array the input array
    5622     *
    5623     * @return A new array containing the existing elements except the occurrences of the specified element.
    5624     * @since 3.10
    5625     */
    5626    public static byte[] removeAllOccurrences(final byte[] array, final byte element) {
    5627        return (byte[]) removeAll((Object) array, indexesOf(array, element));
    5628    }
    5629
    5630    /**
    5631     * Removes the occurrences of the specified element from the specified char array.
    5632     * <p>
    5633     * All subsequent elements are shifted to the left (subtracts one from their indices).
    5634     * If the array doesn't contain such an element, no elements are removed from the array.
    5635     * {@code null} will be returned if the input array is {@code null}.
    5636     * </p>
    5637     *
    5638     * @param element the element to remove
    5639     * @param array the input array
    5640     *
    5641     * @return A new array containing the existing elements except the occurrences of the specified element.
    5642     * @since 3.10
    5643     */
    5644    public static char[] removeAllOccurrences(final char[] array, final char element) {
    5645        return (char[]) removeAll((Object) array, indexesOf(array, element));
    5646    }
    5647
    5648    /**
    5649     * Removes the occurrences of the specified element from the specified double array.
    5650     * <p>
    5651     * All subsequent elements are shifted to the left (subtracts one from their indices).
    5652     * If the array doesn't contain such an element, no elements are removed from the array.
    5653     * {@code null} will be returned if the input array is {@code null}.
    5654     * </p>
    5655     *
    5656     * @param element the element to remove
    5657     * @param array the input array
    5658     *
    5659     * @return A new array containing the existing elements except the occurrences of the specified element.
    5660     * @since 3.10
    5661     */
    5662    public static double[] removeAllOccurrences(final double[] array, final double element) {
    5663        return (double[]) removeAll((Object) array, indexesOf(array, element));
    5664    }
    5665
    5666    /**
    5667     * Removes the occurrences of the specified element from the specified float array.
    5668     * <p>
    5669     * All subsequent elements are shifted to the left (subtracts one from their indices).
    5670     * If the array doesn't contain such an element, no elements are removed from the array.
    5671     * {@code null} will be returned if the input array is {@code null}.
    5672     * </p>
    5673     *
    5674     * @param element the element to remove
    5675     * @param array the input array
    5676     *
    5677     * @return A new array containing the existing elements except the occurrences of the specified element.
    5678     * @since 3.10
    5679     */
    5680    public static float[] removeAllOccurrences(final float[] array, final float element) {
    5681        return (float[]) removeAll((Object) array, indexesOf(array, element));
    5682    }
    5683
    5684    /**
    5685     * Removes the occurrences of the specified element from the specified int array.
    5686     * <p>
    5687     * All subsequent elements are shifted to the left (subtracts one from their indices).
    5688     * If the array doesn't contain such an element, no elements are removed from the array.
    5689     * {@code null} will be returned if the input array is {@code null}.
    5690     * </p>
    5691     *
    5692     * @param element the element to remove
    5693     * @param array the input array
    5694     *
    5695     * @return A new array containing the existing elements except the occurrences of the specified element.
    5696     * @since 3.10
    5697     */
    5698    public static int[] removeAllOccurrences(final int[] array, final int element) {
    5699        return (int[]) removeAll((Object) array, indexesOf(array, element));
    5700    }
    5701
    5702    /**
    5703     * Removes the occurrences of the specified element from the specified long array.
    5704     * <p>
    5705     * All subsequent elements are shifted to the left (subtracts one from their indices).
    5706     * If the array doesn't contain such an element, no elements are removed from the array.
    5707     * {@code null} will be returned if the input array is {@code null}.
    5708     * </p>
    5709     *
    5710     * @param element the element to remove
    5711     * @param array the input array
    5712     *
    5713     * @return A new array containing the existing elements except the occurrences of the specified element.
    5714     * @since 3.10
    5715     */
    5716    public static long[] removeAllOccurrences(final long[] array, final long element) {
    5717        return (long[]) removeAll((Object) array, indexesOf(array, element));
    5718    }
    5719
    5720    /**
    5721     * Removes the occurrences of the specified element from the specified short array.
    5722     * <p>
    5723     * All subsequent elements are shifted to the left (subtracts one from their indices).
    5724     * If the array doesn't contain such an element, no elements are removed from the array.
    5725     * {@code null} will be returned if the input array is {@code null}.
    5726     * </p>
    5727     *
    5728     * @param element the element to remove
    5729     * @param array the input array
    5730     *
    5731     * @return A new array containing the existing elements except the occurrences of the specified element.
    5732     * @since 3.10
    5733     */
    5734    public static short[] removeAllOccurrences(final short[] array, final short element) {
    5735        return (short[]) removeAll((Object) array, indexesOf(array, element));
    5736    }
    5737
    5738    /**
    5739     * Removes the occurrences of the specified element from the specified array.
    5740     * <p>
    5741     * All subsequent elements are shifted to the left (subtracts one from their indices).
    5742     * If the array doesn't contain such an element, no elements are removed from the array.
    5743     * {@code null} will be returned if the input array is {@code null}.
    5744     * </p>
    5745     *
    5746     * @param <T> the type of object in the array
    5747     * @param element the element to remove
    5748     * @param array the input array
    5749     *
    5750     * @return A new array containing the existing elements except the occurrences of the specified element.
    5751     * @since 3.10
    5752     */
    5753    public static <T> T[] removeAllOccurrences(final T[] array, final T element) {
    5754        return (T[]) removeAll((Object) array, indexesOf(array, element));
    5755    }
    5756
    5757    /**
    5758     * Removes the first occurrence of the specified element from the
    5759     * specified array. All subsequent elements are shifted to the left
    5760     * (subtracts one from their indices). If the array doesn't contain
    5761     * such an element, no elements are removed from the array.
    5762     * <p>
    5763     * This method returns a new array with the same elements of the input
    5764     * array except the first occurrence of the specified element. The component
    5765     * type of the returned array is always the same as that of the input
    5766     * array.
    5767     * </p>
    5768     * <pre>
    5769     * ArrayUtils.removeElement(null, true)                = null
    5770     * ArrayUtils.removeElement([], true)                  = []
    5771     * ArrayUtils.removeElement([true], false)             = [true]
    5772     * ArrayUtils.removeElement([true, false], false)      = [true]
    5773     * ArrayUtils.removeElement([true, false, true], true) = [false, true]
    5774     * </pre>
    5775     *
    5776     * @param array  the array to remove the element from, may be {@code null}
    5777     * @param element  the element to be removed
    5778     * @return A new array containing the existing elements except the first
    5779     *         occurrence of the specified element.
    5780     * @since 2.1
    5781     */
    5782    public static boolean[] removeElement(final boolean[] array, final boolean element) {
    5783        final int index = indexOf(array, element);
    5784        return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
    5785    }
    5786
    5787    /**
    5788     * Removes the first occurrence of the specified element from the
    5789     * specified array. All subsequent elements are shifted to the left
    5790     * (subtracts one from their indices). If the array doesn't contain
    5791     * such an element, no elements are removed from the array.
    5792     * <p>
    5793     * This method returns a new array with the same elements of the input
    5794     * array except the first occurrence of the specified element. The component
    5795     * type of the returned array is always the same as that of the input
    5796     * array.
    5797     * </p>
    5798     * <pre>
    5799     * ArrayUtils.removeElement(null, 1)        = null
    5800     * ArrayUtils.removeElement([], 1)          = []
    5801     * ArrayUtils.removeElement([1], 0)         = [1]
    5802     * ArrayUtils.removeElement([1, 0], 0)      = [1]
    5803     * ArrayUtils.removeElement([1, 0, 1], 1)   = [0, 1]
    5804     * </pre>
    5805     *
    5806     * @param array  the array to remove the element from, may be {@code null}
    5807     * @param element  the element to be removed
    5808     * @return A new array containing the existing elements except the first
    5809     *         occurrence of the specified element.
    5810     * @since 2.1
    5811     */
    5812    public static byte[] removeElement(final byte[] array, final byte element) {
    5813        final int index = indexOf(array, element);
    5814        return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
    5815    }
    5816
    5817    /**
    5818     * Removes the first occurrence of the specified element from the
    5819     * specified array. All subsequent elements are shifted to the left
    5820     * (subtracts one from their indices). If the array doesn't contain
    5821     * such an element, no elements are removed from the array.
    5822     * <p>
    5823     * This method returns a new array with the same elements of the input
    5824     * array except the first occurrence of the specified element. The component
    5825     * type of the returned array is always the same as that of the input
    5826     * array.
    5827     * </p>
    5828     * <pre>
    5829     * ArrayUtils.removeElement(null, 'a')            = null
    5830     * ArrayUtils.removeElement([], 'a')              = []
    5831     * ArrayUtils.removeElement(['a'], 'b')           = ['a']
    5832     * ArrayUtils.removeElement(['a', 'b'], 'a')      = ['b']
    5833     * ArrayUtils.removeElement(['a', 'b', 'a'], 'a') = ['b', 'a']
    5834     * </pre>
    5835     *
    5836     * @param array  the array to remove the element from, may be {@code null}
    5837     * @param element  the element to be removed
    5838     * @return A new array containing the existing elements except the first
    5839     *         occurrence of the specified element.
    5840     * @since 2.1
    5841     */
    5842    public static char[] removeElement(final char[] array, final char element) {
    5843        final int index = indexOf(array, element);
    5844        return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
    5845    }
    5846
    5847    /**
    5848     * Removes the first occurrence of the specified element from the
    5849     * specified array. All subsequent elements are shifted to the left
    5850     * (subtracts one from their indices). If the array doesn't contain
    5851     * such an element, no elements are removed from the array.
    5852     * <p>
    5853     * This method returns a new array with the same elements of the input
    5854     * array except the first occurrence of the specified element. The component
    5855     * type of the returned array is always the same as that of the input
    5856     * array.
    5857     * </p>
    5858     * <pre>
    5859     * ArrayUtils.removeElement(null, 1.1)            = null
    5860     * ArrayUtils.removeElement([], 1.1)              = []
    5861     * ArrayUtils.removeElement([1.1], 1.2)           = [1.1]
    5862     * ArrayUtils.removeElement([1.1, 2.3], 1.1)      = [2.3]
    5863     * ArrayUtils.removeElement([1.1, 2.3, 1.1], 1.1) = [2.3, 1.1]
    5864     * </pre>
    5865     *
    5866     * @param array  the array to remove the element from, may be {@code null}
    5867     * @param element  the element to be removed
    5868     * @return A new array containing the existing elements except the first
    5869     *         occurrence of the specified element.
    5870     * @since 2.1
    5871     */
    5872    public static double[] removeElement(final double[] array, final double element) {
    5873        final int index = indexOf(array, element);
    5874        return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
    5875    }
    5876
    5877    /**
    5878     * Removes the first occurrence of the specified element from the
    5879     * specified array. All subsequent elements are shifted to the left
    5880     * (subtracts one from their indices). If the array doesn't contain
    5881     * such an element, no elements are removed from the array.
    5882     * <p>
    5883     * This method returns a new array with the same elements of the input
    5884     * array except the first occurrence of the specified element. The component
    5885     * type of the returned array is always the same as that of the input
    5886     * array.
    5887     * </p>
    5888     * <pre>
    5889     * ArrayUtils.removeElement(null, 1.1)            = null
    5890     * ArrayUtils.removeElement([], 1.1)              = []
    5891     * ArrayUtils.removeElement([1.1], 1.2)           = [1.1]
    5892     * ArrayUtils.removeElement([1.1, 2.3], 1.1)      = [2.3]
    5893     * ArrayUtils.removeElement([1.1, 2.3, 1.1], 1.1) = [2.3, 1.1]
    5894     * </pre>
    5895     *
    5896     * @param array  the array to remove the element from, may be {@code null}
    5897     * @param element  the element to be removed
    5898     * @return A new array containing the existing elements except the first
    5899     *         occurrence of the specified element.
    5900     * @since 2.1
    5901     */
    5902    public static float[] removeElement(final float[] array, final float element) {
    5903        final int index = indexOf(array, element);
    5904        return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
    5905    }
    5906
    5907    /**
    5908     * Removes the first occurrence of the specified element from the
    5909     * specified array. All subsequent elements are shifted to the left
    5910     * (subtracts one from their indices). If the array doesn't contain
    5911     * such an element, no elements are removed from the array.
    5912     * <p>
    5913     * This method returns a new array with the same elements of the input
    5914     * array except the first occurrence of the specified element. The component
    5915     * type of the returned array is always the same as that of the input
    5916     * array.
    5917     * </p>
    5918     * <pre>
    5919     * ArrayUtils.removeElement(null, 1)      = null
    5920     * ArrayUtils.removeElement([], 1)        = []
    5921     * ArrayUtils.removeElement([1], 2)       = [1]
    5922     * ArrayUtils.removeElement([1, 3], 1)    = [3]
    5923     * ArrayUtils.removeElement([1, 3, 1], 1) = [3, 1]
    5924     * </pre>
    5925     *
    5926     * @param array  the array to remove the element from, may be {@code null}
    5927     * @param element  the element to be removed
    5928     * @return A new array containing the existing elements except the first
    5929     *         occurrence of the specified element.
    5930     * @since 2.1
    5931     */
    5932    public static int[] removeElement(final int[] array, final int element) {
    5933        final int index = indexOf(array, element);
    5934        return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
    5935    }
    5936
    5937    /**
    5938     * Removes the first occurrence of the specified element from the
    5939     * specified array. All subsequent elements are shifted to the left
    5940     * (subtracts one from their indices). If the array doesn't contain
    5941     * such an element, no elements are removed from the array.
    5942     * <p>
    5943     * This method returns a new array with the same elements of the input
    5944     * array except the first occurrence of the specified element. The component
    5945     * type of the returned array is always the same as that of the input
    5946     * array.
    5947     * </p>
    5948     * <pre>
    5949     * ArrayUtils.removeElement(null, 1)      = null
    5950     * ArrayUtils.removeElement([], 1)        = []
    5951     * ArrayUtils.removeElement([1], 2)       = [1]
    5952     * ArrayUtils.removeElement([1, 3], 1)    = [3]
    5953     * ArrayUtils.removeElement([1, 3, 1], 1) = [3, 1]
    5954     * </pre>
    5955     *
    5956     * @param array  the array to remove the element from, may be {@code null}
    5957     * @param element  the element to be removed
    5958     * @return A new array containing the existing elements except the first
    5959     *         occurrence of the specified element.
    5960     * @since 2.1
    5961     */
    5962    public static long[] removeElement(final long[] array, final long element) {
    5963        final int index = indexOf(array, element);
    5964        return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
    5965    }
    5966
    5967    /**
    5968     * Removes the first occurrence of the specified element from the
    5969     * specified array. All subsequent elements are shifted to the left
    5970     * (subtracts one from their indices). If the array doesn't contain
    5971     * such an element, no elements are removed from the array.
    5972     * <p>
    5973     * This method returns a new array with the same elements of the input
    5974     * array except the first occurrence of the specified element. The component
    5975     * type of the returned array is always the same as that of the input
    5976     * array.
    5977     * </p>
    5978     * <pre>
    5979     * ArrayUtils.removeElement(null, 1)      = null
    5980     * ArrayUtils.removeElement([], 1)        = []
    5981     * ArrayUtils.removeElement([1], 2)       = [1]
    5982     * ArrayUtils.removeElement([1, 3], 1)    = [3]
    5983     * ArrayUtils.removeElement([1, 3, 1], 1) = [3, 1]
    5984     * </pre>
    5985     *
    5986     * @param array  the array to remove the element from, may be {@code null}
    5987     * @param element  the element to be removed
    5988     * @return A new array containing the existing elements except the first
    5989     *         occurrence of the specified element.
    5990     * @since 2.1
    5991     */
    5992    public static short[] removeElement(final short[] array, final short element) {
    5993        final int index = indexOf(array, element);
    5994        return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
    5995    }
    5996
    5997    /**
    5998     * Removes the first occurrence of the specified element from the
    5999     * specified array. All subsequent elements are shifted to the left
    6000     * (subtracts one from their indices). If the array doesn't contain
    6001     * such an element, no elements are removed from the array.
    6002     * <p>
    6003     * This method returns a new array with the same elements of the input
    6004     * array except the first occurrence of the specified element. The component
    6005     * type of the returned array is always the same as that of the input
    6006     * array.
    6007     * </p>
    6008     * <pre>
    6009     * ArrayUtils.removeElement(null, "a")            = null
    6010     * ArrayUtils.removeElement([], "a")              = []
    6011     * ArrayUtils.removeElement(["a"], "b")           = ["a"]
    6012     * ArrayUtils.removeElement(["a", "b"], "a")      = ["b"]
    6013     * ArrayUtils.removeElement(["a", "b", "a"], "a") = ["b", "a"]
    6014     * </pre>
    6015     *
    6016     * @param <T> the component type of the array
    6017     * @param array  the array to remove the element from, may be {@code null}
    6018     * @param element  the element to be removed
    6019     * @return A new array containing the existing elements except the first
    6020     *         occurrence of the specified element.
    6021     * @since 2.1
    6022     */
    6023    public static <T> T[] removeElement(final T[] array, final Object element) {
    6024        final int index = indexOf(array, element);
    6025        return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
    6026    }
    6027
    6028    /**
    6029     * Removes occurrences of specified elements, in specified quantities,
    6030     * from the specified array. All subsequent elements are shifted left.
    6031     * For any element-to-be-removed specified in greater quantities than
    6032     * contained in the original array, no change occurs beyond the
    6033     * removal of the existing matching items.
    6034     * <p>
    6035     * This method returns a new array with the same elements of the input
    6036     * array except for the earliest-encountered occurrences of the specified
    6037     * elements. The component type of the returned array is always the same
    6038     * as that of the input array.
    6039     * </p>
    6040     * <pre>
    6041     * ArrayUtils.removeElements(null, true, false)               = null
    6042     * ArrayUtils.removeElements([], true, false)                 = []
    6043     * ArrayUtils.removeElements([true], false, false)            = [true]
    6044     * ArrayUtils.removeElements([true, false], true, true)       = [false]
    6045     * ArrayUtils.removeElements([true, false, true], true)       = [false, true]
    6046     * ArrayUtils.removeElements([true, false, true], true, true) = [false]
    6047     * </pre>
    6048     *
    6049     * @param array  the array to remove the element from, may be {@code null}
    6050     * @param values the elements to be removed
    6051     * @return A new array containing the existing elements except the
    6052     *         earliest-encountered occurrences of the specified elements.
    6053     * @since 3.0.1
    6054     */
    6055    public static boolean[] removeElements(final boolean[] array, final boolean... values) {
    6056        if (isEmpty(array) || isEmpty(values)) {
    6057            return clone(array);
    6058        }
    6059        final HashMap<Boolean, MutableInt> occurrences = new HashMap<>(2); // only two possible values here
    6060        for (final boolean v : values) {
    6061            final Boolean boxed = Boolean.valueOf(v);
    6062            final MutableInt count = occurrences.get(boxed);
    6063            if (count == null) {
    6064                occurrences.put(boxed, new MutableInt(1));
    6065            } else {
    6066                count.increment();
    6067            }
    6068        }
    6069        final BitSet toRemove = new BitSet();
    6070        for (int i = 0; i < array.length; i++) {
    6071            final boolean key = array[i];
    6072            final MutableInt count = occurrences.get(key);
    6073            if (count != null) {
    6074                if (count.decrementAndGet() == 0) {
    6075                    occurrences.remove(key);
    6076                }
    6077                toRemove.set(i);
    6078            }
    6079        }
    6080        return (boolean[]) removeAll(array, toRemove);
    6081    }
    6082
    6083    /**
    6084     * Removes occurrences of specified elements, in specified quantities,
    6085     * from the specified array. All subsequent elements are shifted left.
    6086     * For any element-to-be-removed specified in greater quantities than
    6087     * contained in the original array, no change occurs beyond the
    6088     * removal of the existing matching items.
    6089     * <p>
    6090     * This method returns a new array with the same elements of the input
    6091     * array except for the earliest-encountered occurrences of the specified
    6092     * elements. The component type of the returned array is always the same
    6093     * as that of the input array.
    6094     * </p>
    6095     * <pre>
    6096     * ArrayUtils.removeElements(null, 1, 2)      = null
    6097     * ArrayUtils.removeElements([], 1, 2)        = []
    6098     * ArrayUtils.removeElements([1], 2, 3)       = [1]
    6099     * ArrayUtils.removeElements([1, 3], 1, 2)    = [3]
    6100     * ArrayUtils.removeElements([1, 3, 1], 1)    = [3, 1]
    6101     * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
    6102     * </pre>
    6103     *
    6104     * @param array  the array to remove the element from, may be {@code null}
    6105     * @param values the elements to be removed
    6106     * @return A new array containing the existing elements except the
    6107     *         earliest-encountered occurrences of the specified elements.
    6108     * @since 3.0.1
    6109     */
    6110    public static byte[] removeElements(final byte[] array, final byte... values) {
    6111        if (isEmpty(array) || isEmpty(values)) {
    6112            return clone(array);
    6113        }
    6114        final Map<Byte, MutableInt> occurrences = new HashMap<>(values.length);
    6115        for (final byte v : values) {
    6116            final Byte boxed = Byte.valueOf(v);
    6117            final MutableInt count = occurrences.get(boxed);
    6118            if (count == null) {
    6119                occurrences.put(boxed, new MutableInt(1));
    6120            } else {
    6121                count.increment();
    6122            }
    6123        }
    6124        final BitSet toRemove = new BitSet();
    6125        for (int i = 0; i < array.length; i++) {
    6126            final byte key = array[i];
    6127            final MutableInt count = occurrences.get(key);
    6128            if (count != null) {
    6129                if (count.decrementAndGet() == 0) {
    6130                    occurrences.remove(key);
    6131                }
    6132                toRemove.set(i);
    6133            }
    6134        }
    6135        return (byte[]) removeAll(array, toRemove);
    6136    }
    6137
    6138    /**
    6139     * Removes occurrences of specified elements, in specified quantities,
    6140     * from the specified array. All subsequent elements are shifted left.
    6141     * For any element-to-be-removed specified in greater quantities than
    6142     * contained in the original array, no change occurs beyond the
    6143     * removal of the existing matching items.
    6144     * <p>
    6145     * This method returns a new array with the same elements of the input
    6146     * array except for the earliest-encountered occurrences of the specified
    6147     * elements. The component type of the returned array is always the same
    6148     * as that of the input array.
    6149     * </p>
    6150     * <pre>
    6151     * ArrayUtils.removeElements(null, 1, 2)      = null
    6152     * ArrayUtils.removeElements([], 1, 2)        = []
    6153     * ArrayUtils.removeElements([1], 2, 3)       = [1]
    6154     * ArrayUtils.removeElements([1, 3], 1, 2)    = [3]
    6155     * ArrayUtils.removeElements([1, 3, 1], 1)    = [3, 1]
    6156     * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
    6157     * </pre>
    6158     *
    6159     * @param array  the array to remove the element from, may be {@code null}
    6160     * @param values the elements to be removed
    6161     * @return A new array containing the existing elements except the
    6162     *         earliest-encountered occurrences of the specified elements.
    6163     * @since 3.0.1
    6164     */
    6165    public static char[] removeElements(final char[] array, final char... values) {
    6166        if (isEmpty(array) || isEmpty(values)) {
    6167            return clone(array);
    6168        }
    6169        final HashMap<Character, MutableInt> occurrences = new HashMap<>(values.length);
    6170        for (final char v : values) {
    6171            final Character boxed = Character.valueOf(v);
    6172            final MutableInt count = occurrences.get(boxed);
    6173            if (count == null) {
    6174                occurrences.put(boxed, new MutableInt(1));
    6175            } else {
    6176                count.increment();
    6177            }
    6178        }
    6179        final BitSet toRemove = new BitSet();
    6180        for (int i = 0; i < array.length; i++) {
    6181            final char key = array[i];
    6182            final MutableInt count = occurrences.get(key);
    6183            if (count != null) {
    6184                if (count.decrementAndGet() == 0) {
    6185                    occurrences.remove(key);
    6186                }
    6187                toRemove.set(i);
    6188            }
    6189        }
    6190        return (char[]) removeAll(array, toRemove);
    6191    }
    6192
    6193    /**
    6194     * Removes occurrences of specified elements, in specified quantities,
    6195     * from the specified array. All subsequent elements are shifted left.
    6196     * For any element-to-be-removed specified in greater quantities than
    6197     * contained in the original array, no change occurs beyond the
    6198     * removal of the existing matching items.
    6199     * <p>
    6200     * This method returns a new array with the same elements of the input
    6201     * array except for the earliest-encountered occurrences of the specified
    6202     * elements. The component type of the returned array is always the same
    6203     * as that of the input array.
    6204     * </p>
    6205     * <pre>
    6206     * ArrayUtils.removeElements(null, 1, 2)      = null
    6207     * ArrayUtils.removeElements([], 1, 2)        = []
    6208     * ArrayUtils.removeElements([1], 2, 3)       = [1]
    6209     * ArrayUtils.removeElements([1, 3], 1, 2)    = [3]
    6210     * ArrayUtils.removeElements([1, 3, 1], 1)    = [3, 1]
    6211     * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
    6212     * </pre>
    6213     *
    6214     * @param array  the array to remove the element from, may be {@code null}
    6215     * @param values the elements to be removed
    6216     * @return A new array containing the existing elements except the
    6217     *         earliest-encountered occurrences of the specified elements.
    6218     * @since 3.0.1
    6219     */
    6220    public static double[] removeElements(final double[] array, final double... values) {
    6221        if (isEmpty(array) || isEmpty(values)) {
    6222            return clone(array);
    6223        }
    6224        final HashMap<Double, MutableInt> occurrences = new HashMap<>(values.length);
    6225        for (final double v : values) {
    6226            final Double boxed = Double.valueOf(v);
    6227            final MutableInt count = occurrences.get(boxed);
    6228            if (count == null) {
    6229                occurrences.put(boxed, new MutableInt(1));
    6230            } else {
    6231                count.increment();
    6232            }
    6233        }
    6234        final BitSet toRemove = new BitSet();
    6235        for (int i = 0; i < array.length; i++) {
    6236            final double key = array[i];
    6237            final MutableInt count = occurrences.get(key);
    6238            if (count != null) {
    6239                if (count.decrementAndGet() == 0) {
    6240                    occurrences.remove(key);
    6241                }
    6242                toRemove.set(i);
    6243            }
    6244        }
    6245        return (double[]) removeAll(array, toRemove);
    6246    }
    6247
    6248    /**
    6249     * Removes occurrences of specified elements, in specified quantities,
    6250     * from the specified array. All subsequent elements are shifted left.
    6251     * For any element-to-be-removed specified in greater quantities than
    6252     * contained in the original array, no change occurs beyond the
    6253     * removal of the existing matching items.
    6254     * <p>
    6255     * This method returns a new array with the same elements of the input
    6256     * array except for the earliest-encountered occurrences of the specified
    6257     * elements. The component type of the returned array is always the same
    6258     * as that of the input array.
    6259     * </p>
    6260     * <pre>
    6261     * ArrayUtils.removeElements(null, 1, 2)      = null
    6262     * ArrayUtils.removeElements([], 1, 2)        = []
    6263     * ArrayUtils.removeElements([1], 2, 3)       = [1]
    6264     * ArrayUtils.removeElements([1, 3], 1, 2)    = [3]
    6265     * ArrayUtils.removeElements([1, 3, 1], 1)    = [3, 1]
    6266     * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
    6267     * </pre>
    6268     *
    6269     * @param array  the array to remove the element from, may be {@code null}
    6270     * @param values the elements to be removed
    6271     * @return A new array containing the existing elements except the
    6272     *         earliest-encountered occurrences of the specified elements.
    6273     * @since 3.0.1
    6274     */
    6275    public static float[] removeElements(final float[] array, final float... values) {
    6276        if (isEmpty(array) || isEmpty(values)) {
    6277            return clone(array);
    6278        }
    6279        final HashMap<Float, MutableInt> occurrences = new HashMap<>(values.length);
    6280        for (final float v : values) {
    6281            final Float boxed = Float.valueOf(v);
    6282            final MutableInt count = occurrences.get(boxed);
    6283            if (count == null) {
    6284                occurrences.put(boxed, new MutableInt(1));
    6285            } else {
    6286                count.increment();
    6287            }
    6288        }
    6289        final BitSet toRemove = new BitSet();
    6290        for (int i = 0; i < array.length; i++) {
    6291            final float key = array[i];
    6292            final MutableInt count = occurrences.get(key);
    6293            if (count != null) {
    6294                if (count.decrementAndGet() == 0) {
    6295                    occurrences.remove(key);
    6296                }
    6297                toRemove.set(i);
    6298            }
    6299        }
    6300        return (float[]) removeAll(array, toRemove);
    6301    }
    6302
    6303    /**
    6304     * Removes occurrences of specified elements, in specified quantities,
    6305     * from the specified array. All subsequent elements are shifted left.
    6306     * For any element-to-be-removed specified in greater quantities than
    6307     * contained in the original array, no change occurs beyond the
    6308     * removal of the existing matching items.
    6309     * <p>
    6310     * This method returns a new array with the same elements of the input
    6311     * array except for the earliest-encountered occurrences of the specified
    6312     * elements. The component type of the returned array is always the same
    6313     * as that of the input array.
    6314     * </p>
    6315     * <pre>
    6316     * ArrayUtils.removeElements(null, 1, 2)      = null
    6317     * ArrayUtils.removeElements([], 1, 2)        = []
    6318     * ArrayUtils.removeElements([1], 2, 3)       = [1]
    6319     * ArrayUtils.removeElements([1, 3], 1, 2)    = [3]
    6320     * ArrayUtils.removeElements([1, 3, 1], 1)    = [3, 1]
    6321     * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
    6322     * </pre>
    6323     *
    6324     * @param array  the array to remove the element from, may be {@code null}
    6325     * @param values the elements to be removed
    6326     * @return A new array containing the existing elements except the
    6327     *         earliest-encountered occurrences of the specified elements.
    6328     * @since 3.0.1
    6329     */
    6330    public static int[] removeElements(final int[] array, final int... values) {
    6331        if (isEmpty(array) || isEmpty(values)) {
    6332            return clone(array);
    6333        }
    6334        final HashMap<Integer, MutableInt> occurrences = new HashMap<>(values.length);
    6335        for (final int v : values) {
    6336            final Integer boxed = Integer.valueOf(v);
    6337            final MutableInt count = occurrences.get(boxed);
    6338            if (count == null) {
    6339                occurrences.put(boxed, new MutableInt(1));
    6340            } else {
    6341                count.increment();
    6342            }
    6343        }
    6344        final BitSet toRemove = new BitSet();
    6345        for (int i = 0; i < array.length; i++) {
    6346            final int key = array[i];
    6347            final MutableInt count = occurrences.get(key);
    6348            if (count != null) {
    6349                if (count.decrementAndGet() == 0) {
    6350                    occurrences.remove(key);
    6351                }
    6352                toRemove.set(i);
    6353            }
    6354        }
    6355        return (int[]) removeAll(array, toRemove);
    6356    }
    6357
    6358    /**
    6359     * Removes occurrences of specified elements, in specified quantities,
    6360     * from the specified array. All subsequent elements are shifted left.
    6361     * For any element-to-be-removed specified in greater quantities than
    6362     * contained in the original array, no change occurs beyond the
    6363     * removal of the existing matching items.
    6364     * <p>
    6365     * This method returns a new array with the same elements of the input
    6366     * array except for the earliest-encountered occurrences of the specified
    6367     * elements. The component type of the returned array is always the same
    6368     * as that of the input array.
    6369     * </p>
    6370     * <pre>
    6371     * ArrayUtils.removeElements(null, 1, 2)      = null
    6372     * ArrayUtils.removeElements([], 1, 2)        = []
    6373     * ArrayUtils.removeElements([1], 2, 3)       = [1]
    6374     * ArrayUtils.removeElements([1, 3], 1, 2)    = [3]
    6375     * ArrayUtils.removeElements([1, 3, 1], 1)    = [3, 1]
    6376     * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
    6377     * </pre>
    6378     *
    6379     * @param array  the array to remove the element from, may be {@code null}
    6380     * @param values the elements to be removed
    6381     * @return A new array containing the existing elements except the
    6382     *         earliest-encountered occurrences of the specified elements.
    6383     * @since 3.0.1
    6384     */
    6385    public static long[] removeElements(final long[] array, final long... values) {
    6386        if (isEmpty(array) || isEmpty(values)) {
    6387            return clone(array);
    6388        }
    6389        final HashMap<Long, MutableInt> occurrences = new HashMap<>(values.length);
    6390        for (final long v : values) {
    6391            final Long boxed = Long.valueOf(v);
    6392            final MutableInt count = occurrences.get(boxed);
    6393            if (count == null) {
    6394                occurrences.put(boxed, new MutableInt(1));
    6395            } else {
    6396                count.increment();
    6397            }
    6398        }
    6399        final BitSet toRemove = new BitSet();
    6400        for (int i = 0; i < array.length; i++) {
    6401            final long key = array[i];
    6402            final MutableInt count = occurrences.get(key);
    6403            if (count != null) {
    6404                if (count.decrementAndGet() == 0) {
    6405                    occurrences.remove(key);
    6406                }
    6407                toRemove.set(i);
    6408            }
    6409        }
    6410        return (long[]) removeAll(array, toRemove);
    6411    }
    6412
    6413    /**
    6414     * Removes occurrences of specified elements, in specified quantities,
    6415     * from the specified array. All subsequent elements are shifted left.
    6416     * For any element-to-be-removed specified in greater quantities than
    6417     * contained in the original array, no change occurs beyond the
    6418     * removal of the existing matching items.
    6419     * <p>
    6420     * This method returns a new array with the same elements of the input
    6421     * array except for the earliest-encountered occurrences of the specified
    6422     * elements. The component type of the returned array is always the same
    6423     * as that of the input array.
    6424     * </p>
    6425     * <pre>
    6426     * ArrayUtils.removeElements(null, 1, 2)      = null
    6427     * ArrayUtils.removeElements([], 1, 2)        = []
    6428     * ArrayUtils.removeElements([1], 2, 3)       = [1]
    6429     * ArrayUtils.removeElements([1, 3], 1, 2)    = [3]
    6430     * ArrayUtils.removeElements([1, 3, 1], 1)    = [3, 1]
    6431     * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
    6432     * </pre>
    6433     *
    6434     * @param array  the array to remove the element from, may be {@code null}
    6435     * @param values the elements to be removed
    6436     * @return A new array containing the existing elements except the
    6437     *         earliest-encountered occurrences of the specified elements.
    6438     * @since 3.0.1
    6439     */
    6440    public static short[] removeElements(final short[] array, final short... values) {
    6441        if (isEmpty(array) || isEmpty(values)) {
    6442            return clone(array);
    6443        }
    6444        final HashMap<Short, MutableInt> occurrences = new HashMap<>(values.length);
    6445        for (final short v : values) {
    6446            final Short boxed = Short.valueOf(v);
    6447            final MutableInt count = occurrences.get(boxed);
    6448            if (count == null) {
    6449                occurrences.put(boxed, new MutableInt(1));
    6450            } else {
    6451                count.increment();
    6452            }
    6453        }
    6454        final BitSet toRemove = new BitSet();
    6455        for (int i = 0; i < array.length; i++) {
    6456            final short key = array[i];
    6457            final MutableInt count = occurrences.get(key);
    6458            if (count != null) {
    6459                if (count.decrementAndGet() == 0) {
    6460                    occurrences.remove(key);
    6461                }
    6462                toRemove.set(i);
    6463            }
    6464        }
    6465        return (short[]) removeAll(array, toRemove);
    6466    }
    6467
    6468    /**
    6469     * Removes occurrences of specified elements, in specified quantities,
    6470     * from the specified array. All subsequent elements are shifted left.
    6471     * For any element-to-be-removed specified in greater quantities than
    6472     * contained in the original array, no change occurs beyond the
    6473     * removal of the existing matching items.
    6474     * <p>
    6475     * This method returns a new array with the same elements of the input
    6476     * array except for the earliest-encountered occurrences of the specified
    6477     * elements. The component type of the returned array is always the same
    6478     * as that of the input array.
    6479     * </p>
    6480     * <pre>
    6481     * ArrayUtils.removeElements(null, "a", "b")            = null
    6482     * ArrayUtils.removeElements([], "a", "b")              = []
    6483     * ArrayUtils.removeElements(["a"], "b", "c")           = ["a"]
    6484     * ArrayUtils.removeElements(["a", "b"], "a", "c")      = ["b"]
    6485     * ArrayUtils.removeElements(["a", "b", "a"], "a")      = ["b", "a"]
    6486     * ArrayUtils.removeElements(["a", "b", "a"], "a", "a") = ["b"]
    6487     * </pre>
    6488     *
    6489     * @param <T> the component type of the array
    6490     * @param array  the array to remove the element from, may be {@code null}
    6491     * @param values the elements to be removed
    6492     * @return A new array containing the existing elements except the
    6493     *         earliest-encountered occurrences of the specified elements.
    6494     * @since 3.0.1
    6495     */
    6496    @SafeVarargs
    6497    public static <T> T[] removeElements(final T[] array, final T... values) {
    6498        if (isEmpty(array) || isEmpty(values)) {
    6499            return clone(array);
    6500        }
    6501        final HashMap<T, MutableInt> occurrences = new HashMap<>(values.length);
    6502        for (final T v : values) {
    6503            final MutableInt count = occurrences.get(v);
    6504            if (count == null) {
    6505                occurrences.put(v, new MutableInt(1));
    6506            } else {
    6507                count.increment();
    6508            }
    6509        }
    6510        final BitSet toRemove = new BitSet();
    6511        for (int i = 0; i < array.length; i++) {
    6512            final T key = array[i];
    6513            final MutableInt count = occurrences.get(key);
    6514            if (count != null) {
    6515                if (count.decrementAndGet() == 0) {
    6516                    occurrences.remove(key);
    6517                }
    6518                toRemove.set(i);
    6519            }
    6520        }
    6521        @SuppressWarnings("unchecked") // removeAll() always creates an array of the same type as its input
    6522        final T[] result = (T[]) removeAll(array, toRemove);
    6523        return result;
    6524    }
    6525
    6526    /**
    6527     * Reverses the order of the given array.
    6528     * <p>
    6529     * This method does nothing for a {@code null} input array.
    6530     * </p>
    6531     *
    6532     * @param array  the array to reverse, may be {@code null}
    6533     */
    6534    public static void reverse(final boolean[] array) {
    6535        if (array == null) {
    6536            return;
    6537        }
    6538        reverse(array, 0, array.length);
    6539    }
    6540
    6541    /**
    6542     * Reverses the order of the given array in the given range.
    6543     * <p>
    6544     * This method does nothing for a {@code null} input array.
    6545     * </p>
    6546     *
    6547     * @param array
    6548     *            the array to reverse, may be {@code null}
    6549     * @param startIndexInclusive
    6550     *            the starting index. Undervalue (&lt;0) is promoted to 0, overvalue (&gt;array.length) results in no
    6551     *            change.
    6552     * @param endIndexExclusive
    6553     *            elements up to endIndex-1 are reversed in the array. Undervalue (&lt; start index) results in no
    6554     *            change. Overvalue (&gt;array.length) is demoted to array length.
    6555     * @since 3.2
    6556     */
    6557    public static void reverse(final boolean[] array, final int startIndexInclusive, final int endIndexExclusive) {
    6558        if (array == null) {
    6559            return;
    6560        }
    6561        int i = Math.max(startIndexInclusive, 0);
    6562        int j = Math.min(array.length, endIndexExclusive) - 1;
    6563        boolean tmp;
    6564        while (j > i) {
    6565            tmp = array[j];
    6566            array[j] = array[i];
    6567            array[i] = tmp;
    6568            j--;
    6569            i++;
    6570        }
    6571    }
    6572
    6573    /**
    6574     * Reverses the order of the given array.
    6575     * <p>
    6576     * This method does nothing for a {@code null} input array.
    6577     * </p>
    6578     *
    6579     * @param array  the array to reverse, may be {@code null}
    6580     */
    6581    public static void reverse(final byte[] array) {
    6582        if (array != null) {
    6583            reverse(array, 0, array.length);
    6584        }
    6585    }
    6586
    6587    /**
    6588     * Reverses the order of the given array in the given range.
    6589     * <p>
    6590     * This method does nothing for a {@code null} input array.
    6591     * </p>
    6592     *
    6593     * @param array
    6594     *            the array to reverse, may be {@code null}
    6595     * @param startIndexInclusive
    6596     *            the starting index. Undervalue (&lt;0) is promoted to 0, overvalue (&gt;array.length) results in no
    6597     *            change.
    6598     * @param endIndexExclusive
    6599     *            elements up to endIndex-1 are reversed in the array. Undervalue (&lt; start index) results in no
    6600     *            change. Overvalue (&gt;array.length) is demoted to array length.
    6601     * @since 3.2
    6602     */
    6603    public static void reverse(final byte[] array, final int startIndexInclusive, final int endIndexExclusive) {
    6604        if (array == null) {
    6605            return;
    6606        }
    6607        int i = Math.max(startIndexInclusive, 0);
    6608        int j = Math.min(array.length, endIndexExclusive) - 1;
    6609        byte tmp;
    6610        while (j > i) {
    6611            tmp = array[j];
    6612            array[j] = array[i];
    6613            array[i] = tmp;
    6614            j--;
    6615            i++;
    6616        }
    6617    }
    6618
    6619    /**
    6620     * Reverses the order of the given array.
    6621     * <p>
    6622     * This method does nothing for a {@code null} input array.
    6623     * </p>
    6624     *
    6625     * @param array  the array to reverse, may be {@code null}
    6626     */
    6627    public static void reverse(final char[] array) {
    6628        if (array != null) {
    6629            reverse(array, 0, array.length);
    6630        }
    6631    }
    6632
    6633    /**
    6634     * Reverses the order of the given array in the given range.
    6635     * <p>
    6636     * This method does nothing for a {@code null} input array.
    6637     * </p>
    6638     *
    6639     * @param array
    6640     *            the array to reverse, may be {@code null}
    6641     * @param startIndexInclusive
    6642     *            the starting index. Undervalue (&lt;0) is promoted to 0, overvalue (&gt;array.length) results in no
    6643     *            change.
    6644     * @param endIndexExclusive
    6645     *            elements up to endIndex-1 are reversed in the array. Undervalue (&lt; start index) results in no
    6646     *            change. Overvalue (&gt;array.length) is demoted to array length.
    6647     * @since 3.2
    6648     */
    6649    public static void reverse(final char[] array, final int startIndexInclusive, final int endIndexExclusive) {
    6650        if (array == null) {
    6651            return;
    6652        }
    6653        int i = Math.max(startIndexInclusive, 0);
    6654        int j = Math.min(array.length, endIndexExclusive) - 1;
    6655        char tmp;
    6656        while (j > i) {
    6657            tmp = array[j];
    6658            array[j] = array[i];
    6659            array[i] = tmp;
    6660            j--;
    6661            i++;
    6662        }
    6663    }
    6664
    6665    /**
    6666     * Reverses the order of the given array.
    6667     * <p>
    6668     * This method does nothing for a {@code null} input array.
    6669     * </p>
    6670     *
    6671     * @param array  the array to reverse, may be {@code null}
    6672     */
    6673    public static void reverse(final double[] array) {
    6674        if (array != null) {
    6675            reverse(array, 0, array.length);
    6676        }
    6677    }
    6678
    6679    /**
    6680     * Reverses the order of the given array in the given range.
    6681     * <p>
    6682     * This method does nothing for a {@code null} input array.
    6683     * </p>
    6684     *
    6685     * @param array
    6686     *            the array to reverse, may be {@code null}
    6687     * @param startIndexInclusive
    6688     *            the starting index. Undervalue (&lt;0) is promoted to 0, overvalue (&gt;array.length) results in no
    6689     *            change.
    6690     * @param endIndexExclusive
    6691     *            elements up to endIndex-1 are reversed in the array. Undervalue (&lt; start index) results in no
    6692     *            change. Overvalue (&gt;array.length) is demoted to array length.
    6693     * @since 3.2
    6694     */
    6695    public static void reverse(final double[] array, final int startIndexInclusive, final int endIndexExclusive) {
    6696        if (array == null) {
    6697            return;
    6698        }
    6699        int i = Math.max(startIndexInclusive, 0);
    6700        int j = Math.min(array.length, endIndexExclusive) - 1;
    6701        double tmp;
    6702        while (j > i) {
    6703            tmp = array[j];
    6704            array[j] = array[i];
    6705            array[i] = tmp;
    6706            j--;
    6707            i++;
    6708        }
    6709    }
    6710
    6711    /**
    6712     * Reverses the order of the given array.
    6713     * <p>
    6714     * This method does nothing for a {@code null} input array.
    6715     * </p>
    6716     *
    6717     * @param array  the array to reverse, may be {@code null}
    6718     */
    6719    public static void reverse(final float[] array) {
    6720        if (array != null) {
    6721            reverse(array, 0, array.length);
    6722        }
    6723    }
    6724
    6725    /**
    6726     * Reverses the order of the given array in the given range.
    6727     * <p>
    6728     * This method does nothing for a {@code null} input array.
    6729     * </p>
    6730     *
    6731     * @param array
    6732     *            the array to reverse, may be {@code null}
    6733     * @param startIndexInclusive
    6734     *            the starting index. Undervalue (&lt;0) is promoted to 0, overvalue (&gt;array.length) results in no
    6735     *            change.
    6736     * @param endIndexExclusive
    6737     *            elements up to endIndex-1 are reversed in the array. Undervalue (&lt; start index) results in no
    6738     *            change. Overvalue (&gt;array.length) is demoted to array length.
    6739     * @since 3.2
    6740     */
    6741    public static void reverse(final float[] array, final int startIndexInclusive, final int endIndexExclusive) {
    6742        if (array == null) {
    6743            return;
    6744        }
    6745        int i = Math.max(startIndexInclusive, 0);
    6746        int j = Math.min(array.length, endIndexExclusive) - 1;
    6747        float tmp;
    6748        while (j > i) {
    6749            tmp = array[j];
    6750            array[j] = array[i];
    6751            array[i] = tmp;
    6752            j--;
    6753            i++;
    6754        }
    6755    }
    6756
    6757    /**
    6758     * Reverses the order of the given array.
    6759     * <p>
    6760     * This method does nothing for a {@code null} input array.
    6761     * </p>
    6762     *
    6763     * @param array  the array to reverse, may be {@code null}
    6764     */
    6765    public static void reverse(final int[] array) {
    6766        if (array != null) {
    6767            reverse(array, 0, array.length);
    6768        }
    6769    }
    6770
    6771    /**
    6772     * Reverses the order of the given array in the given range.
    6773     * <p>
    6774     * This method does nothing for a {@code null} input array.
    6775     * </p>
    6776     *
    6777     * @param array
    6778     *            the array to reverse, may be {@code null}
    6779     * @param startIndexInclusive
    6780     *            the starting index. Undervalue (&lt;0) is promoted to 0, overvalue (&gt;array.length) results in no
    6781     *            change.
    6782     * @param endIndexExclusive
    6783     *            elements up to endIndex-1 are reversed in the array. Undervalue (&lt; start index) results in no
    6784     *            change. Overvalue (&gt;array.length) is demoted to array length.
    6785     * @since 3.2
    6786     */
    6787    public static void reverse(final int[] array, final int startIndexInclusive, final int endIndexExclusive) {
    6788        if (array == null) {
    6789            return;
    6790        }
    6791        int i = Math.max(startIndexInclusive, 0);
    6792        int j = Math.min(array.length, endIndexExclusive) - 1;
    6793        int tmp;
    6794        while (j > i) {
    6795            tmp = array[j];
    6796            array[j] = array[i];
    6797            array[i] = tmp;
    6798            j--;
    6799            i++;
    6800        }
    6801    }
    6802
    6803    /**
    6804     * Reverses the order of the given array.
    6805     * <p>
    6806     * This method does nothing for a {@code null} input array.
    6807     * </p>
    6808     *
    6809     * @param array  the array to reverse, may be {@code null}
    6810     */
    6811    public static void reverse(final long[] array) {
    6812        if (array != null) {
    6813            reverse(array, 0, array.length);
    6814        }
    6815    }
    6816
    6817    /**
    6818     * Reverses the order of the given array in the given range.
    6819     * <p>
    6820     * This method does nothing for a {@code null} input array.
    6821     * </p>
    6822     *
    6823     * @param array
    6824     *            the array to reverse, may be {@code null}
    6825     * @param startIndexInclusive
    6826     *            the starting index. Undervalue (&lt;0) is promoted to 0, overvalue (&gt;array.length) results in no
    6827     *            change.
    6828     * @param endIndexExclusive
    6829     *            elements up to endIndex-1 are reversed in the array. Undervalue (&lt; start index) results in no
    6830     *            change. Overvalue (&gt;array.length) is demoted to array length.
    6831     * @since 3.2
    6832     */
    6833    public static void reverse(final long[] array, final int startIndexInclusive, final int endIndexExclusive) {
    6834        if (array == null) {
    6835            return;
    6836        }
    6837        int i = Math.max(startIndexInclusive, 0);
    6838        int j = Math.min(array.length, endIndexExclusive) - 1;
    6839        long tmp;
    6840        while (j > i) {
    6841            tmp = array[j];
    6842            array[j] = array[i];
    6843            array[i] = tmp;
    6844            j--;
    6845            i++;
    6846        }
    6847    }
    6848
    6849    /**
    6850     * Reverses the order of the given array.
    6851     * <p>
    6852     * There is no special handling for multi-dimensional arrays.
    6853     * </p>
    6854     * <p>
    6855     * This method does nothing for a {@code null} input array.
    6856     * </p>
    6857     *
    6858     * @param array  the array to reverse, may be {@code null}
    6859     */
    6860    public static void reverse(final Object[] array) {
    6861        if (array != null) {
    6862            reverse(array, 0, array.length);
    6863        }
    6864    }
    6865
    6866    /**
    6867     * Reverses the order of the given array in the given range.
    6868     * <p>
    6869     * This method does nothing for a {@code null} input array.
    6870     * </p>
    6871     *
    6872     * @param array
    6873     *            the array to reverse, may be {@code null}
    6874     * @param startIndexInclusive
    6875     *            the starting index. Under value (&lt;0) is promoted to 0, over value (&gt;array.length) results in no
    6876     *            change.
    6877     * @param endIndexExclusive
    6878     *            elements up to endIndex-1 are reversed in the array. Under value (&lt; start index) results in no
    6879     *            change. Over value (&gt;array.length) is demoted to array length.
    6880     * @since 3.2
    6881     */
    6882    public static void reverse(final Object[] array, final int startIndexInclusive, final int endIndexExclusive) {
    6883        if (array == null) {
    6884            return;
    6885        }
    6886        int i = Math.max(startIndexInclusive, 0);
    6887        int j = Math.min(array.length, endIndexExclusive) - 1;
    6888        Object tmp;
    6889        while (j > i) {
    6890            tmp = array[j];
    6891            array[j] = array[i];
    6892            array[i] = tmp;
    6893            j--;
    6894            i++;
    6895        }
    6896    }
    6897
    6898    /**
    6899     * Reverses the order of the given array.
    6900     * <p>
    6901     * This method does nothing for a {@code null} input array.
    6902     * </p>
    6903     *
    6904     * @param array  the array to reverse, may be {@code null}
    6905     */
    6906    public static void reverse(final short[] array) {
    6907        if (array != null) {
    6908            reverse(array, 0, array.length);
    6909        }
    6910    }
    6911
    6912    /**
    6913     * Reverses the order of the given array in the given range.
    6914     * <p>
    6915     * This method does nothing for a {@code null} input array.
    6916     * </p>
    6917     *
    6918     * @param array
    6919     *            the array to reverse, may be {@code null}
    6920     * @param startIndexInclusive
    6921     *            the starting index. Undervalue (&lt;0) is promoted to 0, overvalue (&gt;array.length) results in no
    6922     *            change.
    6923     * @param endIndexExclusive
    6924     *            elements up to endIndex-1 are reversed in the array. Undervalue (&lt; start index) results in no
    6925     *            change. Overvalue (&gt;array.length) is demoted to array length.
    6926     * @since 3.2
    6927     */
    6928    public static void reverse(final short[] array, final int startIndexInclusive, final int endIndexExclusive) {
    6929        if (array == null) {
    6930            return;
    6931        }
    6932        int i = Math.max(startIndexInclusive, 0);
    6933        int j = Math.min(array.length, endIndexExclusive) - 1;
    6934        short tmp;
    6935        while (j > i) {
    6936            tmp = array[j];
    6937            array[j] = array[i];
    6938            array[i] = tmp;
    6939            j--;
    6940            i++;
    6941        }
    6942    }
    6943
    6944    /**
    6945     * Sets all elements of the specified array, using the provided generator supplier to compute each element.
    6946     * <p>
    6947     * If the generator supplier throws an exception, it is relayed to the caller and the array is left in an indeterminate
    6948     * state.
    6949     * </p>
    6950     *
    6951     * @param <T> type of elements of the array.
    6952     * @param array array to be initialized.
    6953     * @param generator a function accepting an index and producing the desired value for that position.
    6954     * @return the input array
    6955     * @since 3.13.0
    6956     */
    6957    public static <T> T[] setAll(final T[] array, final IntFunction<? extends T> generator) {
    6958        if (array != null && generator != null) {
    6959            Arrays.setAll(array, generator);
    6960        }
    6961        return array;
    6962    }
    6963
    6964    /**
    6965     * Sets all elements of the specified array, using the provided generator supplier to compute each element.
    6966     * <p>
    6967     * If the generator supplier throws an exception, it is relayed to the caller and the array is left in an indeterminate
    6968     * state.
    6969     * </p>
    6970     *
    6971     * @param <T> type of elements of the array.
    6972     * @param array array to be initialized.
    6973     * @param generator a function accepting an index and producing the desired value for that position.
    6974     * @return the input array
    6975     * @since 3.13.0
    6976     */
    6977    public static <T> T[] setAll(final T[] array, final Supplier<? extends T> generator) {
    6978        if (array != null && generator != null) {
    6979            for (int i = 0; i < array.length; i++) {
    6980                array[i] = generator.get();
    6981            }
    6982        }
    6983        return array;
    6984    }
    6985
    6986    /**
    6987     * Shifts the order of the given boolean array.
    6988     *
    6989     * <p>There is no special handling for multi-dimensional arrays. This method
    6990     * does nothing for {@code null} or empty input arrays.</p>
    6991     *
    6992     * @param array  the array to shift, may be {@code null}
    6993     * @param offset
    6994     *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
    6995     *          rotate, than the effective offset is modulo the number of elements to rotate.
    6996     * @since 3.5
    6997     */
    6998    public static void shift(final boolean[] array, final int offset) {
    6999        if (array != null) {
    7000            shift(array, 0, array.length, offset);
    7001        }
    7002    }
    7003
    7004    /**
    7005     * Shifts the order of a series of elements in the given boolean array.
    7006     *
    7007     * <p>There is no special handling for multi-dimensional arrays. This method
    7008     * does nothing for {@code null} or empty input arrays.</p>
    7009     *
    7010     * @param array
    7011     *            the array to shift, may be {@code null}
    7012     * @param startIndexInclusive
    7013     *            the starting index. Undervalue (&lt;0) is promoted to 0, overvalue (&gt;array.length) results in no
    7014     *            change.
    7015     * @param endIndexExclusive
    7016     *            elements up to endIndex-1 are shifted in the array. Undervalue (&lt; start index) results in no
    7017     *            change. Overvalue (&gt;array.length) is demoted to array length.
    7018     * @param offset
    7019     *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
    7020     *          rotate, than the effective offset is modulo the number of elements to rotate.
    7021     * @since 3.5
    7022     */
    7023    public static void shift(final boolean[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
    7024        if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
    7025            return;
    7026        }
    7027        if (startIndexInclusive < 0) {
    7028            startIndexInclusive = 0;
    7029        }
    7030        if (endIndexExclusive >= array.length) {
    7031            endIndexExclusive = array.length;
    7032        }
    7033        int n = endIndexExclusive - startIndexInclusive;
    7034        if (n <= 1) {
    7035            return;
    7036        }
    7037        offset %= n;
    7038        if (offset < 0) {
    7039            offset += n;
    7040        }
    7041        // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
    7042        // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
    7043        while (n > 1 && offset > 0) {
    7044            final int nOffset = n - offset;
    7045
    7046            if (offset > nOffset) {
    7047                swap(array, startIndexInclusive, startIndexInclusive + n - nOffset,  nOffset);
    7048                n = offset;
    7049                offset -= nOffset;
    7050            } else if (offset < nOffset) {
    7051                swap(array, startIndexInclusive, startIndexInclusive + nOffset,  offset);
    7052                startIndexInclusive += offset;
    7053                n = nOffset;
    7054            } else {
    7055                swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
    7056                break;
    7057            }
    7058        }
    7059    }
    7060
    7061    /**
    7062     * Shifts the order of the given byte array.
    7063     *
    7064     * <p>There is no special handling for multi-dimensional arrays. This method
    7065     * does nothing for {@code null} or empty input arrays.</p>
    7066     *
    7067     * @param array  the array to shift, may be {@code null}
    7068     * @param offset
    7069     *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
    7070     *          rotate, than the effective offset is modulo the number of elements to rotate.
    7071     * @since 3.5
    7072     */
    7073    public static void shift(final byte[] array, final int offset) {
    7074        if (array != null) {
    7075            shift(array, 0, array.length, offset);
    7076        }
    7077    }
    7078
    7079    /**
    7080     * Shifts the order of a series of elements in the given byte array.
    7081     *
    7082     * <p>There is no special handling for multi-dimensional arrays. This method
    7083     * does nothing for {@code null} or empty input arrays.</p>
    7084     *
    7085     * @param array
    7086     *            the array to shift, may be {@code null}
    7087     * @param startIndexInclusive
    7088     *            the starting index. Undervalue (&lt;0) is promoted to 0, overvalue (&gt;array.length) results in no
    7089     *            change.
    7090     * @param endIndexExclusive
    7091     *            elements up to endIndex-1 are shifted in the array. Undervalue (&lt; start index) results in no
    7092     *            change. Overvalue (&gt;array.length) is demoted to array length.
    7093     * @param offset
    7094     *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
    7095     *          rotate, than the effective offset is modulo the number of elements to rotate.
    7096     * @since 3.5
    7097     */
    7098    public static void shift(final byte[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
    7099        if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
    7100            return;
    7101        }
    7102        if (startIndexInclusive < 0) {
    7103            startIndexInclusive = 0;
    7104        }
    7105        if (endIndexExclusive >= array.length) {
    7106            endIndexExclusive = array.length;
    7107        }
    7108        int n = endIndexExclusive - startIndexInclusive;
    7109        if (n <= 1) {
    7110            return;
    7111        }
    7112        offset %= n;
    7113        if (offset < 0) {
    7114            offset += n;
    7115        }
    7116        // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
    7117        // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
    7118        while (n > 1 && offset > 0) {
    7119            final int nOffset = n - offset;
    7120
    7121            if (offset > nOffset) {
    7122                swap(array, startIndexInclusive, startIndexInclusive + n - nOffset,  nOffset);
    7123                n = offset;
    7124                offset -= nOffset;
    7125            } else if (offset < nOffset) {
    7126                swap(array, startIndexInclusive, startIndexInclusive + nOffset,  offset);
    7127                startIndexInclusive += offset;
    7128                n = nOffset;
    7129            } else {
    7130                swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
    7131                break;
    7132            }
    7133        }
    7134    }
    7135
    7136    /**
    7137     * Shifts the order of the given char array.
    7138     *
    7139     * <p>There is no special handling for multi-dimensional arrays. This method
    7140     * does nothing for {@code null} or empty input arrays.</p>
    7141     *
    7142     * @param array  the array to shift, may be {@code null}
    7143     * @param offset
    7144     *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
    7145     *          rotate, than the effective offset is modulo the number of elements to rotate.
    7146     * @since 3.5
    7147     */
    7148    public static void shift(final char[] array, final int offset) {
    7149        if (array != null) {
    7150            shift(array, 0, array.length, offset);
    7151        }
    7152    }
    7153
    7154    /**
    7155     * Shifts the order of a series of elements in the given char array.
    7156     *
    7157     * <p>There is no special handling for multi-dimensional arrays. This method
    7158     * does nothing for {@code null} or empty input arrays.</p>
    7159     *
    7160     * @param array
    7161     *            the array to shift, may be {@code null}
    7162     * @param startIndexInclusive
    7163     *            the starting index. Undervalue (&lt;0) is promoted to 0, overvalue (&gt;array.length) results in no
    7164     *            change.
    7165     * @param endIndexExclusive
    7166     *            elements up to endIndex-1 are shifted in the array. Undervalue (&lt; start index) results in no
    7167     *            change. Overvalue (&gt;array.length) is demoted to array length.
    7168     * @param offset
    7169     *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
    7170     *          rotate, than the effective offset is modulo the number of elements to rotate.
    7171     * @since 3.5
    7172     */
    7173    public static void shift(final char[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
    7174        if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
    7175            return;
    7176        }
    7177        if (startIndexInclusive < 0) {
    7178            startIndexInclusive = 0;
    7179        }
    7180        if (endIndexExclusive >= array.length) {
    7181            endIndexExclusive = array.length;
    7182        }
    7183        int n = endIndexExclusive - startIndexInclusive;
    7184        if (n <= 1) {
    7185            return;
    7186        }
    7187        offset %= n;
    7188        if (offset < 0) {
    7189            offset += n;
    7190        }
    7191        // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
    7192        // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
    7193        while (n > 1 && offset > 0) {
    7194            final int nOffset = n - offset;
    7195
    7196            if (offset > nOffset) {
    7197                swap(array, startIndexInclusive, startIndexInclusive + n - nOffset,  nOffset);
    7198                n = offset;
    7199                offset -= nOffset;
    7200            } else if (offset < nOffset) {
    7201                swap(array, startIndexInclusive, startIndexInclusive + nOffset,  offset);
    7202                startIndexInclusive += offset;
    7203                n = nOffset;
    7204            } else {
    7205                swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
    7206                break;
    7207            }
    7208        }
    7209    }
    7210
    7211    /**
    7212     * Shifts the order of the given double array.
    7213     *
    7214     * <p>There is no special handling for multi-dimensional arrays. This method
    7215     * does nothing for {@code null} or empty input arrays.</p>
    7216     *
    7217     * @param array  the array to shift, may be {@code null}
    7218     * @param offset
    7219     *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
    7220     *          rotate, than the effective offset is modulo the number of elements to rotate.
    7221     * @since 3.5
    7222     */
    7223    public static void shift(final double[] array, final int offset) {
    7224        if (array != null) {
    7225            shift(array, 0, array.length, offset);
    7226        }
    7227    }
    7228
    7229    /**
    7230     * Shifts the order of a series of elements in the given double array.
    7231     *
    7232     * <p>There is no special handling for multi-dimensional arrays. This method
    7233     * does nothing for {@code null} or empty input arrays.</p>
    7234     *
    7235     * @param array
    7236     *            the array to shift, may be {@code null}
    7237     * @param startIndexInclusive
    7238     *            the starting index. Undervalue (&lt;0) is promoted to 0, overvalue (&gt;array.length) results in no
    7239     *            change.
    7240     * @param endIndexExclusive
    7241     *            elements up to endIndex-1 are shifted in the array. Undervalue (&lt; start index) results in no
    7242     *            change. Overvalue (&gt;array.length) is demoted to array length.
    7243     * @param offset
    7244     *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
    7245     *          rotate, than the effective offset is modulo the number of elements to rotate.
    7246     * @since 3.5
    7247     */
    7248    public static void shift(final double[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
    7249        if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
    7250            return;
    7251        }
    7252        if (startIndexInclusive < 0) {
    7253            startIndexInclusive = 0;
    7254        }
    7255        if (endIndexExclusive >= array.length) {
    7256            endIndexExclusive = array.length;
    7257        }
    7258        int n = endIndexExclusive - startIndexInclusive;
    7259        if (n <= 1) {
    7260            return;
    7261        }
    7262        offset %= n;
    7263        if (offset < 0) {
    7264            offset += n;
    7265        }
    7266        // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
    7267        // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
    7268        while (n > 1 && offset > 0) {
    7269            final int nOffset = n - offset;
    7270
    7271            if (offset > nOffset) {
    7272                swap(array, startIndexInclusive, startIndexInclusive + n - nOffset,  nOffset);
    7273                n = offset;
    7274                offset -= nOffset;
    7275            } else if (offset < nOffset) {
    7276                swap(array, startIndexInclusive, startIndexInclusive + nOffset,  offset);
    7277                startIndexInclusive += offset;
    7278                n = nOffset;
    7279            } else {
    7280                swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
    7281                break;
    7282            }
    7283        }
    7284    }
    7285
    7286    /**
    7287     * Shifts the order of the given float array.
    7288     *
    7289     * <p>There is no special handling for multi-dimensional arrays. This method
    7290     * does nothing for {@code null} or empty input arrays.</p>
    7291     *
    7292     * @param array  the array to shift, may be {@code null}
    7293     * @param offset
    7294     *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
    7295     *          rotate, than the effective offset is modulo the number of elements to rotate.
    7296     * @since 3.5
    7297     */
    7298    public static void shift(final float[] array, final int offset) {
    7299        if (array != null) {
    7300            shift(array, 0, array.length, offset);
    7301        }
    7302    }
    7303
    7304    /**
    7305     * Shifts the order of a series of elements in the given float array.
    7306     *
    7307     * <p>There is no special handling for multi-dimensional arrays. This method
    7308     * does nothing for {@code null} or empty input arrays.</p>
    7309     *
    7310     * @param array
    7311     *            the array to shift, may be {@code null}
    7312     * @param startIndexInclusive
    7313     *            the starting index. Undervalue (&lt;0) is promoted to 0, overvalue (&gt;array.length) results in no
    7314     *            change.
    7315     * @param endIndexExclusive
    7316     *            elements up to endIndex-1 are shifted in the array. Undervalue (&lt; start index) results in no
    7317     *            change. Overvalue (&gt;array.length) is demoted to array length.
    7318     * @param offset
    7319     *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
    7320     *          rotate, than the effective offset is modulo the number of elements to rotate.
    7321     * @since 3.5
    7322     */
    7323    public static void shift(final float[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
    7324        if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
    7325            return;
    7326        }
    7327        if (startIndexInclusive < 0) {
    7328            startIndexInclusive = 0;
    7329        }
    7330        if (endIndexExclusive >= array.length) {
    7331            endIndexExclusive = array.length;
    7332        }
    7333        int n = endIndexExclusive - startIndexInclusive;
    7334        if (n <= 1) {
    7335            return;
    7336        }
    7337        offset %= n;
    7338        if (offset < 0) {
    7339            offset += n;
    7340        }
    7341        // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
    7342        // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
    7343        while (n > 1 && offset > 0) {
    7344            final int nOffset = n - offset;
    7345
    7346            if (offset > nOffset) {
    7347                swap(array, startIndexInclusive, startIndexInclusive + n - nOffset,  nOffset);
    7348                n = offset;
    7349                offset -= nOffset;
    7350            } else if (offset < nOffset) {
    7351                swap(array, startIndexInclusive, startIndexInclusive + nOffset,  offset);
    7352                startIndexInclusive += offset;
    7353                n = nOffset;
    7354            } else {
    7355                swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
    7356                break;
    7357            }
    7358        }
    7359    }
    7360
    7361    /**
    7362     * Shifts the order of the given int array.
    7363     *
    7364     * <p>There is no special handling for multi-dimensional arrays. This method
    7365     * does nothing for {@code null} or empty input arrays.</p>
    7366     *
    7367     * @param array  the array to shift, may be {@code null}
    7368     * @param offset
    7369     *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
    7370     *          rotate, than the effective offset is modulo the number of elements to rotate.
    7371     * @since 3.5
    7372     */
    7373    public static void shift(final int[] array, final int offset) {
    7374        if (array != null) {
    7375            shift(array, 0, array.length, offset);
    7376        }
    7377    }
    7378
    7379    /**
    7380     * Shifts the order of a series of elements in the given int array.
    7381     *
    7382     * <p>There is no special handling for multi-dimensional arrays. This method
    7383     * does nothing for {@code null} or empty input arrays.</p>
    7384     *
    7385     * @param array
    7386     *            the array to shift, may be {@code null}
    7387     * @param startIndexInclusive
    7388     *            the starting index. Undervalue (&lt;0) is promoted to 0, overvalue (&gt;array.length) results in no
    7389     *            change.
    7390     * @param endIndexExclusive
    7391     *            elements up to endIndex-1 are shifted in the array. Undervalue (&lt; start index) results in no
    7392     *            change. Overvalue (&gt;array.length) is demoted to array length.
    7393     * @param offset
    7394     *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
    7395     *          rotate, than the effective offset is modulo the number of elements to rotate.
    7396     * @since 3.5
    7397     */
    7398    public static void shift(final int[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
    7399        if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
    7400            return;
    7401        }
    7402        if (startIndexInclusive < 0) {
    7403            startIndexInclusive = 0;
    7404        }
    7405        if (endIndexExclusive >= array.length) {
    7406            endIndexExclusive = array.length;
    7407        }
    7408        int n = endIndexExclusive - startIndexInclusive;
    7409        if (n <= 1) {
    7410            return;
    7411        }
    7412        offset %= n;
    7413        if (offset < 0) {
    7414            offset += n;
    7415        }
    7416        // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
    7417        // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
    7418        while (n > 1 && offset > 0) {
    7419            final int nOffset = n - offset;
    7420
    7421            if (offset > nOffset) {
    7422                swap(array, startIndexInclusive, startIndexInclusive + n - nOffset,  nOffset);
    7423                n = offset;
    7424                offset -= nOffset;
    7425            } else if (offset < nOffset) {
    7426                swap(array, startIndexInclusive, startIndexInclusive + nOffset,  offset);
    7427                startIndexInclusive += offset;
    7428                n = nOffset;
    7429            } else {
    7430                swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
    7431                break;
    7432            }
    7433        }
    7434    }
    7435
    7436    /**
    7437     * Shifts the order of the given long array.
    7438     *
    7439     * <p>There is no special handling for multi-dimensional arrays. This method
    7440     * does nothing for {@code null} or empty input arrays.</p>
    7441     *
    7442     * @param array  the array to shift, may be {@code null}
    7443     * @param offset
    7444     *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
    7445     *          rotate, than the effective offset is modulo the number of elements to rotate.
    7446     * @since 3.5
    7447     */
    7448    public static void shift(final long[] array, final int offset) {
    7449        if (array != null) {
    7450            shift(array, 0, array.length, offset);
    7451        }
    7452    }
    7453
    7454    /**
    7455     * Shifts the order of a series of elements in the given long array.
    7456     *
    7457     * <p>There is no special handling for multi-dimensional arrays. This method
    7458     * does nothing for {@code null} or empty input arrays.</p>
    7459     *
    7460     * @param array
    7461     *            the array to shift, may be {@code null}
    7462     * @param startIndexInclusive
    7463     *            the starting index. Undervalue (&lt;0) is promoted to 0, overvalue (&gt;array.length) results in no
    7464     *            change.
    7465     * @param endIndexExclusive
    7466     *            elements up to endIndex-1 are shifted in the array. Undervalue (&lt; start index) results in no
    7467     *            change. Overvalue (&gt;array.length) is demoted to array length.
    7468     * @param offset
    7469     *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
    7470     *          rotate, than the effective offset is modulo the number of elements to rotate.
    7471     * @since 3.5
    7472     */
    7473    public static void shift(final long[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
    7474        if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
    7475            return;
    7476        }
    7477        if (startIndexInclusive < 0) {
    7478            startIndexInclusive = 0;
    7479        }
    7480        if (endIndexExclusive >= array.length) {
    7481            endIndexExclusive = array.length;
    7482        }
    7483        int n = endIndexExclusive - startIndexInclusive;
    7484        if (n <= 1) {
    7485            return;
    7486        }
    7487        offset %= n;
    7488        if (offset < 0) {
    7489            offset += n;
    7490        }
    7491        // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
    7492        // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
    7493        while (n > 1 && offset > 0) {
    7494            final int nOffset = n - offset;
    7495
    7496            if (offset > nOffset) {
    7497                swap(array, startIndexInclusive, startIndexInclusive + n - nOffset,  nOffset);
    7498                n = offset;
    7499                offset -= nOffset;
    7500            } else if (offset < nOffset) {
    7501                swap(array, startIndexInclusive, startIndexInclusive + nOffset,  offset);
    7502                startIndexInclusive += offset;
    7503                n = nOffset;
    7504            } else {
    7505                swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
    7506                break;
    7507            }
    7508        }
    7509    }
    7510
    7511    /**
    7512     * Shifts the order of the given array.
    7513     *
    7514     * <p>There is no special handling for multi-dimensional arrays. This method
    7515     * does nothing for {@code null} or empty input arrays.</p>
    7516     *
    7517     * @param array  the array to shift, may be {@code null}
    7518     * @param offset
    7519     *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
    7520     *          rotate, than the effective offset is modulo the number of elements to rotate.
    7521     * @since 3.5
    7522     */
    7523    public static void shift(final Object[] array, final int offset) {
    7524        if (array != null) {
    7525            shift(array, 0, array.length, offset);
    7526        }
    7527    }
    7528
    7529    /**
    7530     * Shifts the order of a series of elements in the given array.
    7531     *
    7532     * <p>There is no special handling for multi-dimensional arrays. This method
    7533     * does nothing for {@code null} or empty input arrays.</p>
    7534     *
    7535     * @param array
    7536     *            the array to shift, may be {@code null}
    7537     * @param startIndexInclusive
    7538     *            the starting index. Undervalue (&lt;0) is promoted to 0, overvalue (&gt;array.length) results in no
    7539     *            change.
    7540     * @param endIndexExclusive
    7541     *            elements up to endIndex-1 are shifted in the array. Undervalue (&lt; start index) results in no
    7542     *            change. Overvalue (&gt;array.length) is demoted to array length.
    7543     * @param offset
    7544     *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
    7545     *          rotate, than the effective offset is modulo the number of elements to rotate.
    7546     * @since 3.5
    7547     */
    7548    public static void shift(final Object[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
    7549        if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
    7550            return;
    7551        }
    7552        if (startIndexInclusive < 0) {
    7553            startIndexInclusive = 0;
    7554        }
    7555        if (endIndexExclusive >= array.length) {
    7556            endIndexExclusive = array.length;
    7557        }
    7558        int n = endIndexExclusive - startIndexInclusive;
    7559        if (n <= 1) {
    7560            return;
    7561        }
    7562        offset %= n;
    7563        if (offset < 0) {
    7564            offset += n;
    7565        }
    7566        // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
    7567        // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
    7568        while (n > 1 && offset > 0) {
    7569            final int nOffset = n - offset;
    7570
    7571            if (offset > nOffset) {
    7572                swap(array, startIndexInclusive, startIndexInclusive + n - nOffset,  nOffset);
    7573                n = offset;
    7574                offset -= nOffset;
    7575            } else if (offset < nOffset) {
    7576                swap(array, startIndexInclusive, startIndexInclusive + nOffset,  offset);
    7577                startIndexInclusive += offset;
    7578                n = nOffset;
    7579            } else {
    7580                swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
    7581                break;
    7582            }
    7583        }
    7584    }
    7585
    7586    /**
    7587     * Shifts the order of the given short array.
    7588     *
    7589     * <p>There is no special handling for multi-dimensional arrays. This method
    7590     * does nothing for {@code null} or empty input arrays.</p>
    7591     *
    7592     * @param array  the array to shift, may be {@code null}
    7593     * @param offset
    7594     *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
    7595     *          rotate, than the effective offset is modulo the number of elements to rotate.
    7596     * @since 3.5
    7597     */
    7598    public static void shift(final short[] array, final int offset) {
    7599        if (array != null) {
    7600            shift(array, 0, array.length, offset);
    7601        }
    7602    }
    7603
    7604    /**
    7605     * Shifts the order of a series of elements in the given short array.
    7606     *
    7607     * <p>There is no special handling for multi-dimensional arrays. This method
    7608     * does nothing for {@code null} or empty input arrays.</p>
    7609     *
    7610     * @param array
    7611     *            the array to shift, may be {@code null}
    7612     * @param startIndexInclusive
    7613     *            the starting index. Undervalue (&lt;0) is promoted to 0, overvalue (&gt;array.length) results in no
    7614     *            change.
    7615     * @param endIndexExclusive
    7616     *            elements up to endIndex-1 are shifted in the array. Undervalue (&lt; start index) results in no
    7617     *            change. Overvalue (&gt;array.length) is demoted to array length.
    7618     * @param offset
    7619     *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
    7620     *          rotate, than the effective offset is modulo the number of elements to rotate.
    7621     * @since 3.5
    7622     */
    7623    public static void shift(final short[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
    7624        if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
    7625            return;
    7626        }
    7627        if (startIndexInclusive < 0) {
    7628            startIndexInclusive = 0;
    7629        }
    7630        if (endIndexExclusive >= array.length) {
    7631            endIndexExclusive = array.length;
    7632        }
    7633        int n = endIndexExclusive - startIndexInclusive;
    7634        if (n <= 1) {
    7635            return;
    7636        }
    7637        offset %= n;
    7638        if (offset < 0) {
    7639            offset += n;
    7640        }
    7641        // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
    7642        // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
    7643        while (n > 1 && offset > 0) {
    7644            final int nOffset = n - offset;
    7645
    7646            if (offset > nOffset) {
    7647                swap(array, startIndexInclusive, startIndexInclusive + n - nOffset,  nOffset);
    7648                n = offset;
    7649                offset -= nOffset;
    7650            } else if (offset < nOffset) {
    7651                swap(array, startIndexInclusive, startIndexInclusive + nOffset,  offset);
    7652                startIndexInclusive += offset;
    7653                n = nOffset;
    7654            } else {
    7655                swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
    7656                break;
    7657            }
    7658        }
    7659    }
    7660
    7661    /**
    7662     * Randomly permutes the elements of the specified array using the Fisher-Yates algorithm.
    7663     *
    7664     * @param array   the array to shuffle
    7665     * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
    7666     * @since 3.6
    7667     */
    7668    public static void shuffle(final boolean[] array) {
    7669        shuffle(array, random());
    7670    }
    7671
    7672    /**
    7673     * Randomly permutes the elements of the specified array using the Fisher-Yates algorithm.
    7674     *
    7675     * @param array   the array to shuffle
    7676     * @param random  the source of randomness used to permute the elements
    7677     * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
    7678     * @since 3.6
    7679     */
    7680    public static void shuffle(final boolean[] array, final Random random) {
    7681        for (int i = array.length; i > 1; i--) {
    7682            swap(array, i - 1, random.nextInt(i), 1);
    7683        }
    7684    }
    7685
    7686    /**
    7687     * Randomly permutes the elements of the specified array using the Fisher-Yates algorithm.
    7688     *
    7689     * @param array   the array to shuffle
    7690     * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
    7691     * @since 3.6
    7692     */
    7693    public static void shuffle(final byte[] array) {
    7694        shuffle(array, random());
    7695    }
    7696
    7697    /**
    7698     * Randomly permutes the elements of the specified array using the Fisher-Yates algorithm.
    7699     *
    7700     * @param array   the array to shuffle
    7701     * @param random  the source of randomness used to permute the elements
    7702     * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
    7703     * @since 3.6
    7704     */
    7705    public static void shuffle(final byte[] array, final Random random) {
    7706        for (int i = array.length; i > 1; i--) {
    7707            swap(array, i - 1, random.nextInt(i), 1);
    7708        }
    7709    }
    7710
    7711    /**
    7712     * Randomly permutes the elements of the specified array using the Fisher-Yates algorithm.
    7713     *
    7714     * @param array   the array to shuffle
    7715     * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
    7716     * @since 3.6
    7717     */
    7718    public static void shuffle(final char[] array) {
    7719        shuffle(array, random());
    7720    }
    7721
    7722    /**
    7723     * Randomly permutes the elements of the specified array using the Fisher-Yates algorithm.
    7724     *
    7725     * @param array   the array to shuffle
    7726     * @param random  the source of randomness used to permute the elements
    7727     * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
    7728     * @since 3.6
    7729     */
    7730    public static void shuffle(final char[] array, final Random random) {
    7731        for (int i = array.length; i > 1; i--) {
    7732            swap(array, i - 1, random.nextInt(i), 1);
    7733        }
    7734    }
    7735
    7736    /**
    7737     * Randomly permutes the elements of the specified array using the Fisher-Yates algorithm.
    7738     *
    7739     * @param array   the array to shuffle
    7740     * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
    7741     * @since 3.6
    7742     */
    7743    public static void shuffle(final double[] array) {
    7744        shuffle(array, random());
    7745    }
    7746
    7747    /**
    7748     * Randomly permutes the elements of the specified array using the Fisher-Yates algorithm.
    7749     *
    7750     * @param array   the array to shuffle
    7751     * @param random  the source of randomness used to permute the elements
    7752     * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
    7753     * @since 3.6
    7754     */
    7755    public static void shuffle(final double[] array, final Random random) {
    7756        for (int i = array.length; i > 1; i--) {
    7757            swap(array, i - 1, random.nextInt(i), 1);
    7758        }
    7759    }
    7760
    7761    /**
    7762     * Randomly permutes the elements of the specified array using the Fisher-Yates algorithm.
    7763     *
    7764     * @param array   the array to shuffle
    7765     * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
    7766     * @since 3.6
    7767     */
    7768    public static void shuffle(final float[] array) {
    7769        shuffle(array, random());
    7770    }
    7771
    7772    /**
    7773     * Randomly permutes the elements of the specified array using the Fisher-Yates algorithm.
    7774     *
    7775     * @param array   the array to shuffle
    7776     * @param random  the source of randomness used to permute the elements
    7777     * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
    7778     * @since 3.6
    7779     */
    7780    public static void shuffle(final float[] array, final Random random) {
    7781        for (int i = array.length; i > 1; i--) {
    7782            swap(array, i - 1, random.nextInt(i), 1);
    7783        }
    7784    }
    7785
    7786    /**
    7787     * Randomly permutes the elements of the specified array using the Fisher-Yates algorithm.
    7788     *
    7789     * @param array   the array to shuffle
    7790     * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
    7791     * @since 3.6
    7792     */
    7793    public static void shuffle(final int[] array) {
    7794        shuffle(array, random());
    7795    }
    7796
    7797    /**
    7798     * Randomly permutes the elements of the specified array using the Fisher-Yates algorithm.
    7799     *
    7800     * @param array   the array to shuffle
    7801     * @param random  the source of randomness used to permute the elements
    7802     * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
    7803     * @since 3.6
    7804     */
    7805    public static void shuffle(final int[] array, final Random random) {
    7806        for (int i = array.length; i > 1; i--) {
    7807            swap(array, i - 1, random.nextInt(i), 1);
    7808        }
    7809    }
    7810
    7811    /**
    7812     * Randomly permutes the elements of the specified array using the Fisher-Yates algorithm.
    7813     *
    7814     * @param array   the array to shuffle
    7815     * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
    7816     * @since 3.6
    7817     */
    7818    public static void shuffle(final long[] array) {
    7819        shuffle(array, random());
    7820    }
    7821
    7822    /**
    7823     * Randomly permutes the elements of the specified array using the Fisher-Yates algorithm.
    7824     *
    7825     * @param array   the array to shuffle
    7826     * @param random  the source of randomness used to permute the elements
    7827     * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
    7828     * @since 3.6
    7829     */
    7830    public static void shuffle(final long[] array, final Random random) {
    7831        for (int i = array.length; i > 1; i--) {
    7832            swap(array, i - 1, random.nextInt(i), 1);
    7833        }
    7834    }
    7835
    7836    /**
    7837     * Randomly permutes the elements of the specified array using the Fisher-Yates algorithm.
    7838     *
    7839     * @param array   the array to shuffle
    7840     * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
    7841     * @since 3.6
    7842     */
    7843    public static void shuffle(final Object[] array) {
    7844        shuffle(array, random());
    7845    }
    7846
    7847    /**
    7848     * Randomly permutes the elements of the specified array using the Fisher-Yates algorithm.
    7849     *
    7850     * @param array   the array to shuffle
    7851     * @param random  the source of randomness used to permute the elements
    7852     * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
    7853     * @since 3.6
    7854     */
    7855    public static void shuffle(final Object[] array, final Random random) {
    7856        for (int i = array.length; i > 1; i--) {
    7857            swap(array, i - 1, random.nextInt(i), 1);
    7858        }
    7859    }
    7860
    7861    /**
    7862     * Randomly permutes the elements of the specified array using the Fisher-Yates algorithm.
    7863     *
    7864     * @param array   the array to shuffle
    7865     * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
    7866     * @since 3.6
    7867     */
    7868    public static void shuffle(final short[] array) {
    7869        shuffle(array, random());
    7870    }
    7871
    7872    /**
    7873     * Randomly permutes the elements of the specified array using the Fisher-Yates algorithm.
    7874     *
    7875     * @param array   the array to shuffle
    7876     * @param random  the source of randomness used to permute the elements
    7877     * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
    7878     * @since 3.6
    7879     */
    7880    public static void shuffle(final short[] array, final Random random) {
    7881        for (int i = array.length; i > 1; i--) {
    7882            swap(array, i - 1, random.nextInt(i), 1);
    7883        }
    7884    }
    7885
    7886    /**
    7887     * Produces a new {@code boolean} array containing the elements
    7888     * between the start and end indices.
    7889     * <p>
    7890     * The start index is inclusive, the end index exclusive.
    7891     * Null array input produces null output.
    7892     * </p>
    7893     *
    7894     * @param array  the array
    7895     * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
    7896     *      is promoted to 0, overvalue (&gt;array.length) results
    7897     *      in an empty array.
    7898     * @param endIndexExclusive  elements up to endIndex-1 are present in the
    7899     *      returned subarray. Undervalue (&lt; startIndex) produces
    7900     *      empty array, overvalue (&gt;array.length) is demoted to
    7901     *      array length.
    7902     * @return a new array containing the elements between
    7903     *      the start and end indices.
    7904     * @since 2.1
    7905     * @see Arrays#copyOfRange(boolean[], int, int)
    7906     */
    7907    public static boolean[] subarray(final boolean[] array, int startIndexInclusive, int endIndexExclusive) {
    7908        if (array == null) {
    7909            return null;
    7910        }
    7911        if (startIndexInclusive < 0) {
    7912            startIndexInclusive = 0;
    7913        }
    7914        if (endIndexExclusive > array.length) {
    7915            endIndexExclusive = array.length;
    7916        }
    7917        final int newSize = endIndexExclusive - startIndexInclusive;
    7918        if (newSize <= 0) {
    7919            return EMPTY_BOOLEAN_ARRAY;
    7920        }
    7921
    7922        final boolean[] subarray = new boolean[newSize];
    7923        System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
    7924        return subarray;
    7925    }
    7926
    7927    /**
    7928     * Produces a new {@code byte} array containing the elements
    7929     * between the start and end indices.
    7930     * <p>
    7931     * The start index is inclusive, the end index exclusive.
    7932     * Null array input produces null output.
    7933     * </p>
    7934     *
    7935     * @param array  the array
    7936     * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
    7937     *      is promoted to 0, overvalue (&gt;array.length) results
    7938     *      in an empty array.
    7939     * @param endIndexExclusive  elements up to endIndex-1 are present in the
    7940     *      returned subarray. Undervalue (&lt; startIndex) produces
    7941     *      empty array, overvalue (&gt;array.length) is demoted to
    7942     *      array length.
    7943     * @return a new array containing the elements between
    7944     *      the start and end indices.
    7945     * @since 2.1
    7946     * @see Arrays#copyOfRange(byte[], int, int)
    7947     */
    7948    public static byte[] subarray(final byte[] array, int startIndexInclusive, int endIndexExclusive) {
    7949        if (array == null) {
    7950            return null;
    7951        }
    7952        if (startIndexInclusive < 0) {
    7953            startIndexInclusive = 0;
    7954        }
    7955        if (endIndexExclusive > array.length) {
    7956            endIndexExclusive = array.length;
    7957        }
    7958        final int newSize = endIndexExclusive - startIndexInclusive;
    7959        if (newSize <= 0) {
    7960            return EMPTY_BYTE_ARRAY;
    7961        }
    7962
    7963        final byte[] subarray = new byte[newSize];
    7964        System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
    7965        return subarray;
    7966    }
    7967
    7968    /**
    7969     * Produces a new {@code char} array containing the elements
    7970     * between the start and end indices.
    7971     * <p>
    7972     * The start index is inclusive, the end index exclusive.
    7973     * Null array input produces null output.
    7974     * </p>
    7975     *
    7976     * @param array  the array
    7977     * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
    7978     *      is promoted to 0, overvalue (&gt;array.length) results
    7979     *      in an empty array.
    7980     * @param endIndexExclusive  elements up to endIndex-1 are present in the
    7981     *      returned subarray. Undervalue (&lt; startIndex) produces
    7982     *      empty array, overvalue (&gt;array.length) is demoted to
    7983     *      array length.
    7984     * @return a new array containing the elements between
    7985     *      the start and end indices.
    7986     * @since 2.1
    7987     * @see Arrays#copyOfRange(char[], int, int)
    7988     */
    7989    public static char[] subarray(final char[] array, int startIndexInclusive, int endIndexExclusive) {
    7990        if (array == null) {
    7991            return null;
    7992        }
    7993        if (startIndexInclusive < 0) {
    7994            startIndexInclusive = 0;
    7995        }
    7996        if (endIndexExclusive > array.length) {
    7997            endIndexExclusive = array.length;
    7998        }
    7999        final int newSize = endIndexExclusive - startIndexInclusive;
    8000        if (newSize <= 0) {
    8001            return EMPTY_CHAR_ARRAY;
    8002        }
    8003
    8004        final char[] subarray = new char[newSize];
    8005        System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
    8006        return subarray;
    8007    }
    8008
    8009    /**
    8010     * Produces a new {@code double} array containing the elements
    8011     * between the start and end indices.
    8012     * <p>
    8013     * The start index is inclusive, the end index exclusive.
    8014     * Null array input produces null output.
    8015     * </p>
    8016     *
    8017     * @param array  the array
    8018     * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
    8019     *      is promoted to 0, overvalue (&gt;array.length) results
    8020     *      in an empty array.
    8021     * @param endIndexExclusive  elements up to endIndex-1 are present in the
    8022     *      returned subarray. Undervalue (&lt; startIndex) produces
    8023     *      empty array, overvalue (&gt;array.length) is demoted to
    8024     *      array length.
    8025     * @return a new array containing the elements between
    8026     *      the start and end indices.
    8027     * @since 2.1
    8028     * @see Arrays#copyOfRange(double[], int, int)
    8029     */
    8030    public static double[] subarray(final double[] array, int startIndexInclusive, int endIndexExclusive) {
    8031        if (array == null) {
    8032            return null;
    8033        }
    8034        if (startIndexInclusive < 0) {
    8035            startIndexInclusive = 0;
    8036        }
    8037        if (endIndexExclusive > array.length) {
    8038            endIndexExclusive = array.length;
    8039        }
    8040        final int newSize = endIndexExclusive - startIndexInclusive;
    8041        if (newSize <= 0) {
    8042            return EMPTY_DOUBLE_ARRAY;
    8043        }
    8044
    8045        final double[] subarray = new double[newSize];
    8046        System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
    8047        return subarray;
    8048    }
    8049
    8050    /**
    8051     * Produces a new {@code float} array containing the elements
    8052     * between the start and end indices.
    8053     * <p>
    8054     * The start index is inclusive, the end index exclusive.
    8055     * Null array input produces null output.
    8056     * </p>
    8057     *
    8058     * @param array  the array
    8059     * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
    8060     *      is promoted to 0, overvalue (&gt;array.length) results
    8061     *      in an empty array.
    8062     * @param endIndexExclusive  elements up to endIndex-1 are present in the
    8063     *      returned subarray. Undervalue (&lt; startIndex) produces
    8064     *      empty array, overvalue (&gt;array.length) is demoted to
    8065     *      array length.
    8066     * @return a new array containing the elements between
    8067     *      the start and end indices.
    8068     * @since 2.1
    8069     * @see Arrays#copyOfRange(float[], int, int)
    8070     */
    8071    public static float[] subarray(final float[] array, int startIndexInclusive, int endIndexExclusive) {
    8072        if (array == null) {
    8073            return null;
    8074        }
    8075        if (startIndexInclusive < 0) {
    8076            startIndexInclusive = 0;
    8077        }
    8078        if (endIndexExclusive > array.length) {
    8079            endIndexExclusive = array.length;
    8080        }
    8081        final int newSize = endIndexExclusive - startIndexInclusive;
    8082        if (newSize <= 0) {
    8083            return EMPTY_FLOAT_ARRAY;
    8084        }
    8085
    8086        final float[] subarray = new float[newSize];
    8087        System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
    8088        return subarray;
    8089    }
    8090
    8091    /**
    8092     * Produces a new {@code int} array containing the elements
    8093     * between the start and end indices.
    8094     * <p>
    8095     * The start index is inclusive, the end index exclusive.
    8096     * Null array input produces null output.
    8097     * </p>
    8098     *
    8099     * @param array  the array
    8100     * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
    8101     *      is promoted to 0, overvalue (&gt;array.length) results
    8102     *      in an empty array.
    8103     * @param endIndexExclusive  elements up to endIndex-1 are present in the
    8104     *      returned subarray. Undervalue (&lt; startIndex) produces
    8105     *      empty array, overvalue (&gt;array.length) is demoted to
    8106     *      array length.
    8107     * @return a new array containing the elements between
    8108     *      the start and end indices.
    8109     * @since 2.1
    8110     * @see Arrays#copyOfRange(int[], int, int)
    8111     */
    8112    public static int[] subarray(final int[] array, int startIndexInclusive, int endIndexExclusive) {
    8113        if (array == null) {
    8114            return null;
    8115        }
    8116        if (startIndexInclusive < 0) {
    8117            startIndexInclusive = 0;
    8118        }
    8119        if (endIndexExclusive > array.length) {
    8120            endIndexExclusive = array.length;
    8121        }
    8122        final int newSize = endIndexExclusive - startIndexInclusive;
    8123        if (newSize <= 0) {
    8124            return EMPTY_INT_ARRAY;
    8125        }
    8126
    8127        final int[] subarray = new int[newSize];
    8128        System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
    8129        return subarray;
    8130    }
    8131
    8132    /**
    8133     * Produces a new {@code long} array containing the elements
    8134     * between the start and end indices.
    8135     * <p>
    8136     * The start index is inclusive, the end index exclusive.
    8137     * Null array input produces null output.
    8138     * </p>
    8139     *
    8140     * @param array  the array
    8141     * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
    8142     *      is promoted to 0, overvalue (&gt;array.length) results
    8143     *      in an empty array.
    8144     * @param endIndexExclusive  elements up to endIndex-1 are present in the
    8145     *      returned subarray. Undervalue (&lt; startIndex) produces
    8146     *      empty array, overvalue (&gt;array.length) is demoted to
    8147     *      array length.
    8148     * @return a new array containing the elements between
    8149     *      the start and end indices.
    8150     * @since 2.1
    8151     * @see Arrays#copyOfRange(long[], int, int)
    8152     */
    8153    public static long[] subarray(final long[] array, int startIndexInclusive, int endIndexExclusive) {
    8154        if (array == null) {
    8155            return null;
    8156        }
    8157        if (startIndexInclusive < 0) {
    8158            startIndexInclusive = 0;
    8159        }
    8160        if (endIndexExclusive > array.length) {
    8161            endIndexExclusive = array.length;
    8162        }
    8163        final int newSize = endIndexExclusive - startIndexInclusive;
    8164        if (newSize <= 0) {
    8165            return EMPTY_LONG_ARRAY;
    8166        }
    8167
    8168        final long[] subarray = new long[newSize];
    8169        System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
    8170        return subarray;
    8171    }
    8172
    8173    /**
    8174     * Produces a new {@code short} array containing the elements
    8175     * between the start and end indices.
    8176     * <p>
    8177     * The start index is inclusive, the end index exclusive.
    8178     * Null array input produces null output.
    8179     * </p>
    8180     *
    8181     * @param array  the array
    8182     * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
    8183     *      is promoted to 0, overvalue (&gt;array.length) results
    8184     *      in an empty array.
    8185     * @param endIndexExclusive  elements up to endIndex-1 are present in the
    8186     *      returned subarray. Undervalue (&lt; startIndex) produces
    8187     *      empty array, overvalue (&gt;array.length) is demoted to
    8188     *      array length.
    8189     * @return a new array containing the elements between
    8190     *      the start and end indices.
    8191     * @since 2.1
    8192     * @see Arrays#copyOfRange(short[], int, int)
    8193     */
    8194    public static short[] subarray(final short[] array, int startIndexInclusive, int endIndexExclusive) {
    8195        if (array == null) {
    8196            return null;
    8197        }
    8198        if (startIndexInclusive < 0) {
    8199            startIndexInclusive = 0;
    8200        }
    8201        if (endIndexExclusive > array.length) {
    8202            endIndexExclusive = array.length;
    8203        }
    8204        final int newSize = endIndexExclusive - startIndexInclusive;
    8205        if (newSize <= 0) {
    8206            return EMPTY_SHORT_ARRAY;
    8207        }
    8208
    8209        final short[] subarray = new short[newSize];
    8210        System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
    8211        return subarray;
    8212    }
    8213
    8214    /**
    8215     * Produces a new array containing the elements between
    8216     * the start and end indices.
    8217     * <p>
    8218     * The start index is inclusive, the end index exclusive.
    8219     * Null array input produces null output.
    8220     * </p>
    8221     * <p>
    8222     * The component type of the subarray is always the same as
    8223     * that of the input array. Thus, if the input is an array of type
    8224     * {@link Date}, the following usage is envisaged:
    8225     * </p>
    8226     * <pre>
    8227     * Date[] someDates = (Date[]) ArrayUtils.subarray(allDates, 2, 5);
    8228     * </pre>
    8229     *
    8230     * @param <T> the component type of the array
    8231     * @param array  the array
    8232     * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
    8233     *      is promoted to 0, overvalue (&gt;array.length) results
    8234     *      in an empty array.
    8235     * @param endIndexExclusive  elements up to endIndex-1 are present in the
    8236     *      returned subarray. Undervalue (&lt; startIndex) produces
    8237     *      empty array, overvalue (&gt;array.length) is demoted to
    8238     *      array length.
    8239     * @return a new array containing the elements between
    8240     *      the start and end indices.
    8241     * @since 2.1
    8242     * @see Arrays#copyOfRange(Object[], int, int)
    8243     */
    8244    public static <T> T[] subarray(final T[] array, int startIndexInclusive, int endIndexExclusive) {
    8245        if (array == null) {
    8246            return null;
    8247        }
    8248        if (startIndexInclusive < 0) {
    8249            startIndexInclusive = 0;
    8250        }
    8251        if (endIndexExclusive > array.length) {
    8252            endIndexExclusive = array.length;
    8253        }
    8254        final int newSize = endIndexExclusive - startIndexInclusive;
    8255        final Class<T> type = getComponentType(array);
    8256        if (newSize <= 0) {
    8257            return newInstance(type, 0);
    8258        }
    8259        final T[] subarray = newInstance(type, newSize);
    8260        System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
    8261        return subarray;
    8262    }
    8263
    8264    /**
    8265     * Swaps two elements in the given boolean array.
    8266     *
    8267     * <p>There is no special handling for multi-dimensional arrays. This method
    8268     * does nothing for a {@code null} or empty input array or for overflow indices.
    8269     * Negative indices are promoted to 0(zero).</p>
    8270     *
    8271     * Examples:
    8272     * <ul>
    8273     *     <li>ArrayUtils.swap([1, 2, 3], 0, 2) -&gt; [3, 2, 1]</li>
    8274     *     <li>ArrayUtils.swap([1, 2, 3], 0, 0) -&gt; [1, 2, 3]</li>
    8275     *     <li>ArrayUtils.swap([1, 2, 3], 1, 0) -&gt; [2, 1, 3]</li>
    8276     *     <li>ArrayUtils.swap([1, 2, 3], 0, 5) -&gt; [1, 2, 3]</li>
    8277     *     <li>ArrayUtils.swap([1, 2, 3], -1, 1) -&gt; [2, 1, 3]</li>
    8278     * </ul>
    8279     *
    8280     * @param array  the array to swap, may be {@code null}
    8281     * @param offset1 the index of the first element to swap
    8282     * @param offset2 the index of the second element to swap
    8283     * @since 3.5
    8284     */
    8285    public static void swap(final boolean[] array, final int offset1, final int offset2) {
    8286        swap(array, offset1, offset2, 1);
    8287    }
    8288
    8289
    8290    /**
    8291     * Swaps a series of elements in the given boolean array.
    8292     *
    8293     * <p>This method does nothing for a {@code null} or empty input array or
    8294     * for overflow indices. Negative indices are promoted to 0(zero). If any
    8295     * of the sub-arrays to swap falls outside of the given array, then the
    8296     * swap is stopped at the end of the array and as many as possible elements
    8297     * are swapped.</p>
    8298     *
    8299     * Examples:
    8300     * <ul>
    8301     *     <li>ArrayUtils.swap([true, false, true, false], 0, 2, 1) -&gt; [true, false, true, false]</li>
    8302     *     <li>ArrayUtils.swap([true, false, true, false], 0, 0, 1) -&gt; [true, false, true, false]</li>
    8303     *     <li>ArrayUtils.swap([true, false, true, false], 0, 2, 2) -&gt; [true, false, true, false]</li>
    8304     *     <li>ArrayUtils.swap([true, false, true, false], -3, 2, 2) -&gt; [true, false, true, false]</li>
    8305     *     <li>ArrayUtils.swap([true, false, true, false], 0, 3, 3) -&gt; [false, false, true, true]</li>
    8306     * </ul>
    8307     *
    8308     * @param array the array to swap, may be {@code null}
    8309     * @param offset1 the index of the first element in the series to swap
    8310     * @param offset2 the index of the second element in the series to swap
    8311     * @param len the number of elements to swap starting with the given indices
    8312     * @since 3.5
    8313     */
    8314    public static void swap(final boolean[] array, int offset1, int offset2, int len) {
    8315        if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
    8316            return;
    8317        }
    8318        if (offset1 < 0) {
    8319            offset1 = 0;
    8320        }
    8321        if (offset2 < 0) {
    8322            offset2 = 0;
    8323        }
    8324        len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
    8325        for (int i = 0; i < len; i++, offset1++, offset2++) {
    8326            final boolean aux = array[offset1];
    8327            array[offset1] = array[offset2];
    8328            array[offset2] = aux;
    8329        }
    8330    }
    8331
    8332    /**
    8333     * Swaps two elements in the given byte array.
    8334     *
    8335     * <p>There is no special handling for multi-dimensional arrays. This method
    8336     * does nothing for a {@code null} or empty input array or for overflow indices.
    8337     * Negative indices are promoted to 0(zero).</p>
    8338     *
    8339     * Examples:
    8340     * <ul>
    8341     *     <li>ArrayUtils.swap([1, 2, 3], 0, 2) -&gt; [3, 2, 1]</li>
    8342     *     <li>ArrayUtils.swap([1, 2, 3], 0, 0) -&gt; [1, 2, 3]</li>
    8343     *     <li>ArrayUtils.swap([1, 2, 3], 1, 0) -&gt; [2, 1, 3]</li>
    8344     *     <li>ArrayUtils.swap([1, 2, 3], 0, 5) -&gt; [1, 2, 3]</li>
    8345     *     <li>ArrayUtils.swap([1, 2, 3], -1, 1) -&gt; [2, 1, 3]</li>
    8346     * </ul>
    8347     *
    8348     * @param array  the array to swap, may be {@code null}
    8349     * @param offset1 the index of the first element to swap
    8350     * @param offset2 the index of the second element to swap
    8351     * @since 3.5
    8352     */
    8353    public static void swap(final byte[] array, final int offset1, final int offset2) {
    8354        swap(array, offset1, offset2, 1);
    8355    }
    8356
    8357    /**
    8358     * Swaps a series of elements in the given byte array.
    8359     *
    8360     * <p>This method does nothing for a {@code null} or empty input array or
    8361     * for overflow indices. Negative indices are promoted to 0(zero). If any
    8362     * of the sub-arrays to swap falls outside of the given array, then the
    8363     * swap is stopped at the end of the array and as many as possible elements
    8364     * are swapped.</p>
    8365     *
    8366     * Examples:
    8367     * <ul>
    8368     *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 2, 1) -&gt; [3, 2, 1, 4]</li>
    8369     *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 0, 1) -&gt; [1, 2, 3, 4]</li>
    8370     *     <li>ArrayUtils.swap([1, 2, 3, 4], 2, 0, 2) -&gt; [3, 4, 1, 2]</li>
    8371     *     <li>ArrayUtils.swap([1, 2, 3, 4], -3, 2, 2) -&gt; [3, 4, 1, 2]</li>
    8372     *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 3, 3) -&gt; [4, 2, 3, 1]</li>
    8373     * </ul>
    8374     *
    8375     * @param array the array to swap, may be {@code null}
    8376     * @param offset1 the index of the first element in the series to swap
    8377     * @param offset2 the index of the second element in the series to swap
    8378     * @param len the number of elements to swap starting with the given indices
    8379     * @since 3.5
    8380     */
    8381    public static void swap(final byte[] array, int offset1, int offset2, int len) {
    8382        if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
    8383            return;
    8384        }
    8385        if (offset1 < 0) {
    8386            offset1 = 0;
    8387        }
    8388        if (offset2 < 0) {
    8389            offset2 = 0;
    8390        }
    8391        len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
    8392        for (int i = 0; i < len; i++, offset1++, offset2++) {
    8393            final byte aux = array[offset1];
    8394            array[offset1] = array[offset2];
    8395            array[offset2] = aux;
    8396        }
    8397    }
    8398
    8399    /**
    8400     * Swaps two elements in the given char array.
    8401     *
    8402     * <p>There is no special handling for multi-dimensional arrays. This method
    8403     * does nothing for a {@code null} or empty input array or for overflow indices.
    8404     * Negative indices are promoted to 0(zero).</p>
    8405     *
    8406     * Examples:
    8407     * <ul>
    8408     *     <li>ArrayUtils.swap([1, 2, 3], 0, 2) -&gt; [3, 2, 1]</li>
    8409     *     <li>ArrayUtils.swap([1, 2, 3], 0, 0) -&gt; [1, 2, 3]</li>
    8410     *     <li>ArrayUtils.swap([1, 2, 3], 1, 0) -&gt; [2, 1, 3]</li>
    8411     *     <li>ArrayUtils.swap([1, 2, 3], 0, 5) -&gt; [1, 2, 3]</li>
    8412     *     <li>ArrayUtils.swap([1, 2, 3], -1, 1) -&gt; [2, 1, 3]</li>
    8413     * </ul>
    8414     *
    8415     * @param array  the array to swap, may be {@code null}
    8416     * @param offset1 the index of the first element to swap
    8417     * @param offset2 the index of the second element to swap
    8418     * @since 3.5
    8419     */
    8420    public static void swap(final char[] array, final int offset1, final int offset2) {
    8421        swap(array, offset1, offset2, 1);
    8422    }
    8423
    8424    /**
    8425     * Swaps a series of elements in the given char array.
    8426     *
    8427     * <p>This method does nothing for a {@code null} or empty input array or
    8428     * for overflow indices. Negative indices are promoted to 0(zero). If any
    8429     * of the sub-arrays to swap falls outside of the given array, then the
    8430     * swap is stopped at the end of the array and as many as possible elements
    8431     * are swapped.</p>
    8432     *
    8433     * Examples:
    8434     * <ul>
    8435     *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 2, 1) -&gt; [3, 2, 1, 4]</li>
    8436     *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 0, 1) -&gt; [1, 2, 3, 4]</li>
    8437     *     <li>ArrayUtils.swap([1, 2, 3, 4], 2, 0, 2) -&gt; [3, 4, 1, 2]</li>
    8438     *     <li>ArrayUtils.swap([1, 2, 3, 4], -3, 2, 2) -&gt; [3, 4, 1, 2]</li>
    8439     *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 3, 3) -&gt; [4, 2, 3, 1]</li>
    8440     * </ul>
    8441     *
    8442     * @param array the array to swap, may be {@code null}
    8443     * @param offset1 the index of the first element in the series to swap
    8444     * @param offset2 the index of the second element in the series to swap
    8445     * @param len the number of elements to swap starting with the given indices
    8446     * @since 3.5
    8447     */
    8448    public static void swap(final char[] array, int offset1, int offset2, int len) {
    8449        if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
    8450            return;
    8451        }
    8452        if (offset1 < 0) {
    8453            offset1 = 0;
    8454        }
    8455        if (offset2 < 0) {
    8456            offset2 = 0;
    8457        }
    8458        len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
    8459        for (int i = 0; i < len; i++, offset1++, offset2++) {
    8460            final char aux = array[offset1];
    8461            array[offset1] = array[offset2];
    8462            array[offset2] = aux;
    8463        }
    8464    }
    8465
    8466    /**
    8467     * Swaps two elements in the given double array.
    8468     *
    8469     * <p>There is no special handling for multi-dimensional arrays. This method
    8470     * does nothing for a {@code null} or empty input array or for overflow indices.
    8471     * Negative indices are promoted to 0(zero).</p>
    8472     *
    8473     * Examples:
    8474     * <ul>
    8475     *     <li>ArrayUtils.swap([1, 2, 3], 0, 2) -&gt; [3, 2, 1]</li>
    8476     *     <li>ArrayUtils.swap([1, 2, 3], 0, 0) -&gt; [1, 2, 3]</li>
    8477     *     <li>ArrayUtils.swap([1, 2, 3], 1, 0) -&gt; [2, 1, 3]</li>
    8478     *     <li>ArrayUtils.swap([1, 2, 3], 0, 5) -&gt; [1, 2, 3]</li>
    8479     *     <li>ArrayUtils.swap([1, 2, 3], -1, 1) -&gt; [2, 1, 3]</li>
    8480     * </ul>
    8481     *
    8482     * @param array  the array to swap, may be {@code null}
    8483     * @param offset1 the index of the first element to swap
    8484     * @param offset2 the index of the second element to swap
    8485     * @since 3.5
    8486     */
    8487    public static void swap(final double[] array, final int offset1, final int offset2) {
    8488        swap(array, offset1, offset2, 1);
    8489    }
    8490
    8491    /**
    8492     * Swaps a series of elements in the given double array.
    8493     *
    8494     * <p>This method does nothing for a {@code null} or empty input array or
    8495     * for overflow indices. Negative indices are promoted to 0(zero). If any
    8496     * of the sub-arrays to swap falls outside of the given array, then the
    8497     * swap is stopped at the end of the array and as many as possible elements
    8498     * are swapped.</p>
    8499     *
    8500     * Examples:
    8501     * <ul>
    8502     *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 2, 1) -&gt; [3, 2, 1, 4]</li>
    8503     *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 0, 1) -&gt; [1, 2, 3, 4]</li>
    8504     *     <li>ArrayUtils.swap([1, 2, 3, 4], 2, 0, 2) -&gt; [3, 4, 1, 2]</li>
    8505     *     <li>ArrayUtils.swap([1, 2, 3, 4], -3, 2, 2) -&gt; [3, 4, 1, 2]</li>
    8506     *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 3, 3) -&gt; [4, 2, 3, 1]</li>
    8507     * </ul>
    8508     *
    8509     * @param array the array to swap, may be {@code null}
    8510     * @param offset1 the index of the first element in the series to swap
    8511     * @param offset2 the index of the second element in the series to swap
    8512     * @param len the number of elements to swap starting with the given indices
    8513     * @since 3.5
    8514     */
    8515    public static void swap(final double[] array,  int offset1, int offset2, int len) {
    8516        if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
    8517            return;
    8518        }
    8519        if (offset1 < 0) {
    8520            offset1 = 0;
    8521        }
    8522        if (offset2 < 0) {
    8523            offset2 = 0;
    8524        }
    8525        len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
    8526        for (int i = 0; i < len; i++, offset1++, offset2++) {
    8527            final double aux = array[offset1];
    8528            array[offset1] = array[offset2];
    8529            array[offset2] = aux;
    8530        }
    8531    }
    8532
    8533    /**
    8534     * Swaps two elements in the given float array.
    8535     *
    8536     * <p>There is no special handling for multi-dimensional arrays. This method
    8537     * does nothing for a {@code null} or empty input array or for overflow indices.
    8538     * Negative indices are promoted to 0(zero).</p>
    8539     *
    8540     * Examples:
    8541     * <ul>
    8542     *     <li>ArrayUtils.swap([1, 2, 3], 0, 2) -&gt; [3, 2, 1]</li>
    8543     *     <li>ArrayUtils.swap([1, 2, 3], 0, 0) -&gt; [1, 2, 3]</li>
    8544     *     <li>ArrayUtils.swap([1, 2, 3], 1, 0) -&gt; [2, 1, 3]</li>
    8545     *     <li>ArrayUtils.swap([1, 2, 3], 0, 5) -&gt; [1, 2, 3]</li>
    8546     *     <li>ArrayUtils.swap([1, 2, 3], -1, 1) -&gt; [2, 1, 3]</li>
    8547     * </ul>
    8548     *
    8549     * @param array  the array to swap, may be {@code null}
    8550     * @param offset1 the index of the first element to swap
    8551     * @param offset2 the index of the second element to swap
    8552     * @since 3.5
    8553     */
    8554    public static void swap(final float[] array, final int offset1, final int offset2) {
    8555        swap(array, offset1, offset2, 1);
    8556    }
    8557
    8558    /**
    8559     * Swaps a series of elements in the given float array.
    8560     *
    8561     * <p>This method does nothing for a {@code null} or empty input array or
    8562     * for overflow indices. Negative indices are promoted to 0(zero). If any
    8563     * of the sub-arrays to swap falls outside of the given array, then the
    8564     * swap is stopped at the end of the array and as many as possible elements
    8565     * are swapped.</p>
    8566     *
    8567     * Examples:
    8568     * <ul>
    8569     *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 2, 1) -&gt; [3, 2, 1, 4]</li>
    8570     *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 0, 1) -&gt; [1, 2, 3, 4]</li>
    8571     *     <li>ArrayUtils.swap([1, 2, 3, 4], 2, 0, 2) -&gt; [3, 4, 1, 2]</li>
    8572     *     <li>ArrayUtils.swap([1, 2, 3, 4], -3, 2, 2) -&gt; [3, 4, 1, 2]</li>
    8573     *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 3, 3) -&gt; [4, 2, 3, 1]</li>
    8574     * </ul>
    8575     *
    8576     * @param array the array to swap, may be {@code null}
    8577     * @param offset1 the index of the first element in the series to swap
    8578     * @param offset2 the index of the second element in the series to swap
    8579     * @param len the number of elements to swap starting with the given indices
    8580     * @since 3.5
    8581     */
    8582    public static void swap(final float[] array, int offset1, int offset2, int len) {
    8583        if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
    8584            return;
    8585        }
    8586        if (offset1 < 0) {
    8587            offset1 = 0;
    8588        }
    8589        if (offset2 < 0) {
    8590            offset2 = 0;
    8591        }
    8592        len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
    8593        for (int i = 0; i < len; i++, offset1++, offset2++) {
    8594            final float aux = array[offset1];
    8595            array[offset1] = array[offset2];
    8596            array[offset2] = aux;
    8597        }
    8598
    8599    }
    8600
    8601    /**
    8602     * Swaps two elements in the given int array.
    8603     *
    8604     * <p>There is no special handling for multi-dimensional arrays. This method
    8605     * does nothing for a {@code null} or empty input array or for overflow indices.
    8606     * Negative indices are promoted to 0(zero).</p>
    8607     *
    8608     * Examples:
    8609     * <ul>
    8610     *     <li>ArrayUtils.swap([1, 2, 3], 0, 2) -&gt; [3, 2, 1]</li>
    8611     *     <li>ArrayUtils.swap([1, 2, 3], 0, 0) -&gt; [1, 2, 3]</li>
    8612     *     <li>ArrayUtils.swap([1, 2, 3], 1, 0) -&gt; [2, 1, 3]</li>
    8613     *     <li>ArrayUtils.swap([1, 2, 3], 0, 5) -&gt; [1, 2, 3]</li>
    8614     *     <li>ArrayUtils.swap([1, 2, 3], -1, 1) -&gt; [2, 1, 3]</li>
    8615     * </ul>
    8616     *
    8617     * @param array  the array to swap, may be {@code null}
    8618     * @param offset1 the index of the first element to swap
    8619     * @param offset2 the index of the second element to swap
    8620     * @since 3.5
    8621     */
    8622    public static void swap(final int[] array, final int offset1, final int offset2) {
    8623        swap(array, offset1, offset2, 1);
    8624    }
    8625
    8626    /**
    8627     * Swaps a series of elements in the given int array.
    8628     *
    8629     * <p>This method does nothing for a {@code null} or empty input array or
    8630     * for overflow indices. Negative indices are promoted to 0(zero). If any
    8631     * of the sub-arrays to swap falls outside of the given array, then the
    8632     * swap is stopped at the end of the array and as many as possible elements
    8633     * are swapped.</p>
    8634     *
    8635     * Examples:
    8636     * <ul>
    8637     *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 2, 1) -&gt; [3, 2, 1, 4]</li>
    8638     *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 0, 1) -&gt; [1, 2, 3, 4]</li>
    8639     *     <li>ArrayUtils.swap([1, 2, 3, 4], 2, 0, 2) -&gt; [3, 4, 1, 2]</li>
    8640     *     <li>ArrayUtils.swap([1, 2, 3, 4], -3, 2, 2) -&gt; [3, 4, 1, 2]</li>
    8641     *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 3, 3) -&gt; [4, 2, 3, 1]</li>
    8642     * </ul>
    8643     *
    8644     * @param array the array to swap, may be {@code null}
    8645     * @param offset1 the index of the first element in the series to swap
    8646     * @param offset2 the index of the second element in the series to swap
    8647     * @param len the number of elements to swap starting with the given indices
    8648     * @since 3.5
    8649     */
    8650    public static void swap(final int[] array,  int offset1, int offset2, int len) {
    8651        if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
    8652            return;
    8653        }
    8654        if (offset1 < 0) {
    8655            offset1 = 0;
    8656        }
    8657        if (offset2 < 0) {
    8658            offset2 = 0;
    8659        }
    8660        len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
    8661        for (int i = 0; i < len; i++, offset1++, offset2++) {
    8662            final int aux = array[offset1];
    8663            array[offset1] = array[offset2];
    8664            array[offset2] = aux;
    8665        }
    8666    }
    8667
    8668    /**
    8669     * Swaps two elements in the given long array.
    8670     *
    8671     * <p>There is no special handling for multi-dimensional arrays. This method
    8672     * does nothing for a {@code null} or empty input array or for overflow indices.
    8673     * Negative indices are promoted to 0(zero).</p>
    8674     *
    8675     * Examples:
    8676     * <ul>
    8677     *     <li>ArrayUtils.swap([true, false, true], 0, 2) -&gt; [true, false, true]</li>
    8678     *     <li>ArrayUtils.swap([true, false, true], 0, 0) -&gt; [true, false, true]</li>
    8679     *     <li>ArrayUtils.swap([true, false, true], 1, 0) -&gt; [false, true, true]</li>
    8680     *     <li>ArrayUtils.swap([true, false, true], 0, 5) -&gt; [true, false, true]</li>
    8681     *     <li>ArrayUtils.swap([true, false, true], -1, 1) -&gt; [false, true, true]</li>
    8682     * </ul>
    8683     *
    8684     * @param array  the array to swap, may be {@code null}
    8685     * @param offset1 the index of the first element to swap
    8686     * @param offset2 the index of the second element to swap
    8687     * @since 3.5
    8688     */
    8689    public static void swap(final long[] array, final int offset1, final int offset2) {
    8690        swap(array, offset1, offset2, 1);
    8691    }
    8692
    8693    /**
    8694     * Swaps a series of elements in the given long array.
    8695     *
    8696     * <p>This method does nothing for a {@code null} or empty input array or
    8697     * for overflow indices. Negative indices are promoted to 0(zero). If any
    8698     * of the sub-arrays to swap falls outside of the given array, then the
    8699     * swap is stopped at the end of the array and as many as possible elements
    8700     * are swapped.</p>
    8701     *
    8702     * Examples:
    8703     * <ul>
    8704     *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 2, 1) -&gt; [3, 2, 1, 4]</li>
    8705     *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 0, 1) -&gt; [1, 2, 3, 4]</li>
    8706     *     <li>ArrayUtils.swap([1, 2, 3, 4], 2, 0, 2) -&gt; [3, 4, 1, 2]</li>
    8707     *     <li>ArrayUtils.swap([1, 2, 3, 4], -3, 2, 2) -&gt; [3, 4, 1, 2]</li>
    8708     *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 3, 3) -&gt; [4, 2, 3, 1]</li>
    8709     * </ul>
    8710     *
    8711     * @param array the array to swap, may be {@code null}
    8712     * @param offset1 the index of the first element in the series to swap
    8713     * @param offset2 the index of the second element in the series to swap
    8714     * @param len the number of elements to swap starting with the given indices
    8715     * @since 3.5
    8716     */
    8717    public static void swap(final long[] array,  int offset1, int offset2, int len) {
    8718        if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
    8719            return;
    8720        }
    8721        if (offset1 < 0) {
    8722            offset1 = 0;
    8723        }
    8724        if (offset2 < 0) {
    8725            offset2 = 0;
    8726        }
    8727        len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
    8728        for (int i = 0; i < len; i++, offset1++, offset2++) {
    8729            final long aux = array[offset1];
    8730            array[offset1] = array[offset2];
    8731            array[offset2] = aux;
    8732        }
    8733    }
    8734
    8735    /**
    8736     * Swaps two elements in the given array.
    8737     *
    8738     * <p>There is no special handling for multi-dimensional arrays. This method
    8739     * does nothing for a {@code null} or empty input array or for overflow indices.
    8740     * Negative indices are promoted to 0(zero).</p>
    8741     *
    8742     * Examples:
    8743     * <ul>
    8744     *     <li>ArrayUtils.swap(["1", "2", "3"], 0, 2) -&gt; ["3", "2", "1"]</li>
    8745     *     <li>ArrayUtils.swap(["1", "2", "3"], 0, 0) -&gt; ["1", "2", "3"]</li>
    8746     *     <li>ArrayUtils.swap(["1", "2", "3"], 1, 0) -&gt; ["2", "1", "3"]</li>
    8747     *     <li>ArrayUtils.swap(["1", "2", "3"], 0, 5) -&gt; ["1", "2", "3"]</li>
    8748     *     <li>ArrayUtils.swap(["1", "2", "3"], -1, 1) -&gt; ["2", "1", "3"]</li>
    8749     * </ul>
    8750     *
    8751     * @param array the array to swap, may be {@code null}
    8752     * @param offset1 the index of the first element to swap
    8753     * @param offset2 the index of the second element to swap
    8754     * @since 3.5
    8755     */
    8756    public static void swap(final Object[] array, final int offset1, final int offset2) {
    8757        swap(array, offset1, offset2, 1);
    8758    }
    8759
    8760    /**
    8761     * Swaps a series of elements in the given array.
    8762     *
    8763     * <p>This method does nothing for a {@code null} or empty input array or
    8764     * for overflow indices. Negative indices are promoted to 0(zero). If any
    8765     * of the sub-arrays to swap falls outside of the given array, then the
    8766     * swap is stopped at the end of the array and as many as possible elements
    8767     * are swapped.</p>
    8768     *
    8769     * Examples:
    8770     * <ul>
    8771     *     <li>ArrayUtils.swap(["1", "2", "3", "4"], 0, 2, 1) -&gt; ["3", "2", "1", "4"]</li>
    8772     *     <li>ArrayUtils.swap(["1", "2", "3", "4"], 0, 0, 1) -&gt; ["1", "2", "3", "4"]</li>
    8773     *     <li>ArrayUtils.swap(["1", "2", "3", "4"], 2, 0, 2) -&gt; ["3", "4", "1", "2"]</li>
    8774     *     <li>ArrayUtils.swap(["1", "2", "3", "4"], -3, 2, 2) -&gt; ["3", "4", "1", "2"]</li>
    8775     *     <li>ArrayUtils.swap(["1", "2", "3", "4"], 0, 3, 3) -&gt; ["4", "2", "3", "1"]</li>
    8776     * </ul>
    8777     *
    8778     * @param array the array to swap, may be {@code null}
    8779     * @param offset1 the index of the first element in the series to swap
    8780     * @param offset2 the index of the second element in the series to swap
    8781     * @param len the number of elements to swap starting with the given indices
    8782     * @since 3.5
    8783     */
    8784    public static void swap(final Object[] array,  int offset1, int offset2, int len) {
    8785        if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
    8786            return;
    8787        }
    8788        if (offset1 < 0) {
    8789            offset1 = 0;
    8790        }
    8791        if (offset2 < 0) {
    8792            offset2 = 0;
    8793        }
    8794        len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
    8795        for (int i = 0; i < len; i++, offset1++, offset2++) {
    8796            final Object aux = array[offset1];
    8797            array[offset1] = array[offset2];
    8798            array[offset2] = aux;
    8799        }
    8800    }
    8801
    8802    /**
    8803     * Swaps two elements in the given short array.
    8804     *
    8805     * <p>There is no special handling for multi-dimensional arrays. This method
    8806     * does nothing for a {@code null} or empty input array or for overflow indices.
    8807     * Negative indices are promoted to 0(zero).</p>
    8808     *
    8809     * Examples:
    8810     * <ul>
    8811     *     <li>ArrayUtils.swap([1, 2, 3], 0, 2) -&gt; [3, 2, 1]</li>
    8812     *     <li>ArrayUtils.swap([1, 2, 3], 0, 0) -&gt; [1, 2, 3]</li>
    8813     *     <li>ArrayUtils.swap([1, 2, 3], 1, 0) -&gt; [2, 1, 3]</li>
    8814     *     <li>ArrayUtils.swap([1, 2, 3], 0, 5) -&gt; [1, 2, 3]</li>
    8815     *     <li>ArrayUtils.swap([1, 2, 3], -1, 1) -&gt; [2, 1, 3]</li>
    8816     * </ul>
    8817     *
    8818     * @param array  the array to swap, may be {@code null}
    8819     * @param offset1 the index of the first element to swap
    8820     * @param offset2 the index of the second element to swap
    8821     * @since 3.5
    8822     */
    8823    public static void swap(final short[] array, final int offset1, final int offset2) {
    8824        swap(array, offset1, offset2, 1);
    8825    }
    8826
    8827    /**
    8828     * Swaps a series of elements in the given short array.
    8829     *
    8830     * <p>This method does nothing for a {@code null} or empty input array or
    8831     * for overflow indices. Negative indices are promoted to 0(zero). If any
    8832     * of the sub-arrays to swap falls outside of the given array, then the
    8833     * swap is stopped at the end of the array and as many as possible elements
    8834     * are swapped.</p>
    8835     *
    8836     * Examples:
    8837     * <ul>
    8838     *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 2, 1) -&gt; [3, 2, 1, 4]</li>
    8839     *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 0, 1) -&gt; [1, 2, 3, 4]</li>
    8840     *     <li>ArrayUtils.swap([1, 2, 3, 4], 2, 0, 2) -&gt; [3, 4, 1, 2]</li>
    8841     *     <li>ArrayUtils.swap([1, 2, 3, 4], -3, 2, 2) -&gt; [3, 4, 1, 2]</li>
    8842     *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 3, 3) -&gt; [4, 2, 3, 1]</li>
    8843     * </ul>
    8844     *
    8845     * @param array the array to swap, may be {@code null}
    8846     * @param offset1 the index of the first element in the series to swap
    8847     * @param offset2 the index of the second element in the series to swap
    8848     * @param len the number of elements to swap starting with the given indices
    8849     * @since 3.5
    8850     */
    8851    public static void swap(final short[] array, int offset1, int offset2, int len) {
    8852        if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
    8853            return;
    8854        }
    8855        if (offset1 < 0) {
    8856            offset1 = 0;
    8857        }
    8858        if (offset2 < 0) {
    8859            offset2 = 0;
    8860        }
    8861        if (offset1 == offset2) {
    8862            return;
    8863        }
    8864        len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
    8865        for (int i = 0; i < len; i++, offset1++, offset2++) {
    8866            final short aux = array[offset1];
    8867            array[offset1] = array[offset2];
    8868            array[offset2] = aux;
    8869        }
    8870    }
    8871
    8872    /**
    8873     * Create a type-safe generic array.
    8874     * <p>
    8875     * The Java language does not allow an array to be created from a generic type:
    8876     * </p>
    8877     * <pre>
    8878    public static &lt;T&gt; T[] createAnArray(int size) {
    8879        return new T[size]; // compiler error here
    8880    }
    8881    public static &lt;T&gt; T[] createAnArray(int size) {
    8882        return (T[]) new Object[size]; // ClassCastException at runtime
    8883    }
    8884     * </pre>
    8885     * <p>
    8886     * Therefore new arrays of generic types can be created with this method.
    8887     * For example, an array of Strings can be created:
    8888     * </p>
    8889     * <pre>
    8890    String[] array = ArrayUtils.toArray("1", "2");
    8891    String[] emptyArray = ArrayUtils.&lt;String&gt;toArray();
    8892     * </pre>
    8893     * <p>
    8894     * The method is typically used in scenarios, where the caller itself uses generic types
    8895     * that have to be combined into an array.
    8896     * </p>
    8897     * <p>
    8898     * Note, this method makes only sense to provide arguments of the same type so that the
    8899     * compiler can deduce the type of the array itself. While it is possible to select the
    8900     * type explicitly like in
    8901     * {@code Number[] array = ArrayUtils.&lt;Number&gt;toArray(Integer.valueOf(42), Double.valueOf(Math.PI))},
    8902     * there is no real advantage when compared to
    8903     * {@code new Number[] {Integer.valueOf(42), Double.valueOf(Math.PI)}}.
    8904     * </p>
    8905     *
    8906     * @param  <T>   the array's element type
    8907     * @param  items  the varargs array items, null allowed
    8908     * @return the array, not null unless a null array is passed in
    8909     * @since 3.0
    8910     */
    8911    public static <T> T[] toArray(@SuppressWarnings("unchecked") final T... items) {
    8912        return items;
    8913    }
    8914
    8915    /**
    8916     * Converts the given array into a {@link java.util.Map}. Each element of the array
    8917     * must be either a {@link java.util.Map.Entry} or an Array, containing at least two
    8918     * elements, where the first element is used as key and the second as
    8919     * value.
    8920     * <p>
    8921     * This method can be used to initialize:
    8922     * </p>
    8923     * <pre>
    8924     * // Create a Map mapping colors.
    8925     * Map colorMap = ArrayUtils.toMap(new String[][] {
    8926     *     {"RED", "#FF0000"},
    8927     *     {"GREEN", "#00FF00"},
    8928     *     {"BLUE", "#0000FF"}});
    8929     * </pre>
    8930     * <p>
    8931     * This method returns {@code null} for a {@code null} input array.
    8932     * </p>
    8933     *
    8934     * @param array  an array whose elements are either a {@link java.util.Map.Entry} or
    8935     *  an Array containing at least two elements, may be {@code null}
    8936     * @return a {@link Map} that was created from the array
    8937     * @throws IllegalArgumentException  if one element of this Array is
    8938     *  itself an Array containing less than two elements
    8939     * @throws IllegalArgumentException  if the array contains elements other
    8940     *  than {@link java.util.Map.Entry} and an Array
    8941     */
    8942    public static Map<Object, Object> toMap(final Object[] array) {
    8943        if (array == null) {
    8944            return null;
    8945        }
    8946        final Map<Object, Object> map = new HashMap<>((int) (array.length * 1.5));
    8947        for (int i = 0; i < array.length; i++) {
    8948            final Object object = array[i];
    8949            if (object instanceof Map.Entry<?, ?>) {
    8950                final Map.Entry<?, ?> entry = (Map.Entry<?, ?>) object;
    8951                map.put(entry.getKey(), entry.getValue());
    8952            } else if (object instanceof Object[]) {
    8953                final Object[] entry = (Object[]) object;
    8954                if (entry.length < 2) {
    8955                    throw new IllegalArgumentException("Array element " + i + ", '"
    8956                        + object
    8957                        + "', has a length less than 2");
    8958                }
    8959                map.put(entry[0], entry[1]);
    8960            } else {
    8961                throw new IllegalArgumentException("Array element " + i + ", '"
    8962                        + object
    8963                        + "', is neither of type Map.Entry nor an Array");
    8964            }
    8965        }
    8966        return map;
    8967    }
    8968
    8969    /**
    8970     * Converts an array of primitive booleans to objects.
    8971     *
    8972     * <p>This method returns {@code null} for a {@code null} input array.</p>
    8973     *
    8974     * @param array  a {@code boolean} array
    8975     * @return a {@link Boolean} array, {@code null} if null array input
    8976     */
    8977    public static Boolean[] toObject(final boolean[] array) {
    8978        if (array == null) {
    8979            return null;
    8980        }
    8981        if (array.length == 0) {
    8982            return EMPTY_BOOLEAN_OBJECT_ARRAY;
    8983        }
    8984        final Boolean[] result = new Boolean[array.length];
    8985        return setAll(result, i -> array[i] ? Boolean.TRUE : Boolean.FALSE);
    8986    }
    8987
    8988    /**
    8989     * Converts an array of primitive bytes to objects.
    8990     *
    8991     * <p>This method returns {@code null} for a {@code null} input array.</p>
    8992     *
    8993     * @param array  a {@code byte} array
    8994     * @return a {@link Byte} array, {@code null} if null array input
    8995     */
    8996    public static Byte[] toObject(final byte[] array) {
    8997        if (array == null) {
    8998            return null;
    8999        }
    9000        if (array.length == 0) {
    9001            return EMPTY_BYTE_OBJECT_ARRAY;
    9002        }
    9003        return setAll(new Byte[array.length], i -> Byte.valueOf(array[i]));
    9004    }
    9005
    9006    /**
    9007     * Converts an array of primitive chars to objects.
    9008     *
    9009     * <p>This method returns {@code null} for a {@code null} input array.</p>
    9010     *
    9011     * @param array a {@code char} array
    9012     * @return a {@link Character} array, {@code null} if null array input
    9013     */
    9014    public static Character[] toObject(final char[] array) {
    9015        if (array == null) {
    9016            return null;
    9017        }
    9018        if (array.length == 0) {
    9019            return EMPTY_CHARACTER_OBJECT_ARRAY;
    9020        }
    9021        return setAll(new Character[array.length], i -> Character.valueOf(array[i]));
    9022     }
    9023
    9024    /**
    9025     * Converts an array of primitive doubles to objects.
    9026     *
    9027     * <p>This method returns {@code null} for a {@code null} input array.</p>
    9028     *
    9029     * @param array  a {@code double} array
    9030     * @return a {@link Double} array, {@code null} if null array input
    9031     */
    9032    public static Double[] toObject(final double[] array) {
    9033        if (array == null) {
    9034            return null;
    9035        }
    9036        if (array.length == 0) {
    9037            return EMPTY_DOUBLE_OBJECT_ARRAY;
    9038        }
    9039        return setAll(new Double[array.length], i -> Double.valueOf(array[i]));
    9040    }
    9041
    9042    /**
    9043     * Converts an array of primitive floats to objects.
    9044     *
    9045     * <p>This method returns {@code null} for a {@code null} input array.</p>
    9046     *
    9047     * @param array  a {@code float} array
    9048     * @return a {@link Float} array, {@code null} if null array input
    9049     */
    9050    public static Float[] toObject(final float[] array) {
    9051        if (array == null) {
    9052            return null;
    9053        }
    9054        if (array.length == 0) {
    9055            return EMPTY_FLOAT_OBJECT_ARRAY;
    9056        }
    9057        return setAll(new Float[array.length], i -> Float.valueOf(array[i]));
    9058    }
    9059
    9060    /**
    9061     * Converts an array of primitive ints to objects.
    9062     *
    9063     * <p>This method returns {@code null} for a {@code null} input array.</p>
    9064     *
    9065     * @param array  an {@code int} array
    9066     * @return an {@link Integer} array, {@code null} if null array input
    9067     */
    9068    public static Integer[] toObject(final int[] array) {
    9069        if (array == null) {
    9070            return null;
    9071        }
    9072        if (array.length == 0) {
    9073            return EMPTY_INTEGER_OBJECT_ARRAY;
    9074        }
    9075        return setAll(new Integer[array.length], i -> Integer.valueOf(array[i]));
    9076    }
    9077
    9078    /**
    9079     * Converts an array of primitive longs to objects.
    9080     *
    9081     * <p>This method returns {@code null} for a {@code null} input array.</p>
    9082     *
    9083     * @param array  a {@code long} array
    9084     * @return a {@link Long} array, {@code null} if null array input
    9085     */
    9086    public static Long[] toObject(final long[] array) {
    9087        if (array == null) {
    9088            return null;
    9089        }
    9090        if (array.length == 0) {
    9091            return EMPTY_LONG_OBJECT_ARRAY;
    9092        }
    9093        return setAll(new Long[array.length], i -> Long.valueOf(array[i]));
    9094    }
    9095
    9096    /**
    9097     * Converts an array of primitive shorts to objects.
    9098     *
    9099     * <p>This method returns {@code null} for a {@code null} input array.</p>
    9100     *
    9101     * @param array  a {@code short} array
    9102     * @return a {@link Short} array, {@code null} if null array input
    9103     */
    9104    public static Short[] toObject(final short[] array) {
    9105        if (array == null) {
    9106            return null;
    9107        }
    9108        if (array.length == 0) {
    9109            return EMPTY_SHORT_OBJECT_ARRAY;
    9110        }
    9111        return setAll(new Short[array.length], i -> Short.valueOf(array[i]));
    9112    }
    9113
    9114    /**
    9115     * Converts an array of object Booleans to primitives.
    9116     * <p>
    9117     * This method returns {@code null} for a {@code null} input array.
    9118     * </p>
    9119     * <p>
    9120     * Null array elements map to false, like {@code Boolean.parseBoolean(null)} and its callers return false.
    9121     * </p>
    9122     *
    9123     * @param array a {@link Boolean} array, may be {@code null}
    9124     * @return a {@code boolean} array, {@code null} if null array input
    9125     */
    9126    public static boolean[] toPrimitive(final Boolean[] array) {
    9127        return toPrimitive(array, false);
    9128    }
    9129
    9130    /**
    9131     * Converts an array of object Booleans to primitives handling {@code null}.
    9132     * <p>
    9133     * This method returns {@code null} for a {@code null} input array.
    9134     * </p>
    9135     *
    9136     * @param array  a {@link Boolean} array, may be {@code null}
    9137     * @param valueForNull  the value to insert if {@code null} found
    9138     * @return a {@code boolean} array, {@code null} if null array input
    9139     */
    9140    public static boolean[] toPrimitive(final Boolean[] array, final boolean valueForNull) {
    9141        if (array == null) {
    9142            return null;
    9143        }
    9144        if (array.length == 0) {
    9145            return EMPTY_BOOLEAN_ARRAY;
    9146        }
    9147        final boolean[] result = new boolean[array.length];
    9148        for (int i = 0; i < array.length; i++) {
    9149            final Boolean b = array[i];
    9150            result[i] = b == null ? valueForNull : b.booleanValue();
    9151        }
    9152        return result;
    9153    }
    9154
    9155    /**
    9156     * Converts an array of object Bytes to primitives.
    9157     * <p>
    9158     * This method returns {@code null} for a {@code null} input array.
    9159     * </p>
    9160     *
    9161     * @param array  a {@link Byte} array, may be {@code null}
    9162     * @return a {@code byte} array, {@code null} if null array input
    9163     * @throws NullPointerException if an array element is {@code null}
    9164     */
    9165    public static byte[] toPrimitive(final Byte[] array) {
    9166        if (array == null) {
    9167            return null;
    9168        }
    9169        if (array.length == 0) {
    9170            return EMPTY_BYTE_ARRAY;
    9171        }
    9172        final byte[] result = new byte[array.length];
    9173        for (int i = 0; i < array.length; i++) {
    9174            result[i] = array[i].byteValue();
    9175        }
    9176        return result;
    9177    }
    9178
    9179    /**
    9180     * Converts an array of object Bytes to primitives handling {@code null}.
    9181     * <p>
    9182     * This method returns {@code null} for a {@code null} input array.
    9183     * </p>
    9184     *
    9185     * @param array  a {@link Byte} array, may be {@code null}
    9186     * @param valueForNull  the value to insert if {@code null} found
    9187     * @return a {@code byte} array, {@code null} if null array input
    9188     */
    9189    public static byte[] toPrimitive(final Byte[] array, final byte valueForNull) {
    9190        if (array == null) {
    9191            return null;
    9192        }
    9193        if (array.length == 0) {
    9194            return EMPTY_BYTE_ARRAY;
    9195        }
    9196        final byte[] result = new byte[array.length];
    9197        for (int i = 0; i < array.length; i++) {
    9198            final Byte b = array[i];
    9199            result[i] = b == null ? valueForNull : b.byteValue();
    9200        }
    9201        return result;
    9202    }
    9203
    9204    /**
    9205     * Converts an array of object Characters to primitives.
    9206     * <p>
    9207     * This method returns {@code null} for a {@code null} input array.
    9208     * </p>
    9209     *
    9210     * @param array  a {@link Character} array, may be {@code null}
    9211     * @return a {@code char} array, {@code null} if null array input
    9212     * @throws NullPointerException if an array element is {@code null}
    9213     */
    9214    public static char[] toPrimitive(final Character[] array) {
    9215        if (array == null) {
    9216            return null;
    9217        }
    9218        if (array.length == 0) {
    9219            return EMPTY_CHAR_ARRAY;
    9220        }
    9221        final char[] result = new char[array.length];
    9222        for (int i = 0; i < array.length; i++) {
    9223            result[i] = array[i].charValue();
    9224        }
    9225        return result;
    9226    }
    9227
    9228    /**
    9229     * Converts an array of object Character to primitives handling {@code null}.
    9230     * <p>
    9231     * This method returns {@code null} for a {@code null} input array.
    9232     * </p>
    9233     *
    9234     * @param array  a {@link Character} array, may be {@code null}
    9235     * @param valueForNull  the value to insert if {@code null} found
    9236     * @return a {@code char} array, {@code null} if null array input
    9237     */
    9238    public static char[] toPrimitive(final Character[] array, final char valueForNull) {
    9239        if (array == null) {
    9240            return null;
    9241        }
    9242        if (array.length == 0) {
    9243            return EMPTY_CHAR_ARRAY;
    9244        }
    9245        final char[] result = new char[array.length];
    9246        for (int i = 0; i < array.length; i++) {
    9247            final Character b = array[i];
    9248            result[i] = b == null ? valueForNull : b.charValue();
    9249        }
    9250        return result;
    9251    }
    9252
    9253    /**
    9254     * Converts an array of object Doubles to primitives.
    9255     * <p>
    9256     * This method returns {@code null} for a {@code null} input array.
    9257     * </p>
    9258     *
    9259     * @param array  a {@link Double} array, may be {@code null}
    9260     * @return a {@code double} array, {@code null} if null array input
    9261     * @throws NullPointerException if an array element is {@code null}
    9262     */
    9263    public static double[] toPrimitive(final Double[] array) {
    9264        if (array == null) {
    9265            return null;
    9266        }
    9267        if (array.length == 0) {
    9268            return EMPTY_DOUBLE_ARRAY;
    9269        }
    9270        final double[] result = new double[array.length];
    9271        for (int i = 0; i < array.length; i++) {
    9272            result[i] = array[i].doubleValue();
    9273        }
    9274        return result;
    9275    }
    9276
    9277    /**
    9278     * Converts an array of object Doubles to primitives handling {@code null}.
    9279     * <p>
    9280     * This method returns {@code null} for a {@code null} input array.
    9281     * </p>
    9282     *
    9283     * @param array  a {@link Double} array, may be {@code null}
    9284     * @param valueForNull  the value to insert if {@code null} found
    9285     * @return a {@code double} array, {@code null} if null array input
    9286     */
    9287    public static double[] toPrimitive(final Double[] array, final double valueForNull) {
    9288        if (array == null) {
    9289            return null;
    9290        }
    9291        if (array.length == 0) {
    9292            return EMPTY_DOUBLE_ARRAY;
    9293        }
    9294        final double[] result = new double[array.length];
    9295        for (int i = 0; i < array.length; i++) {
    9296            final Double b = array[i];
    9297            result[i] = b == null ? valueForNull : b.doubleValue();
    9298        }
    9299        return result;
    9300    }
    9301
    9302    /**
    9303     * Converts an array of object Floats to primitives.
    9304     * <p>
    9305     * This method returns {@code null} for a {@code null} input array.
    9306     * </p>
    9307     *
    9308     * @param array  a {@link Float} array, may be {@code null}
    9309     * @return a {@code float} array, {@code null} if null array input
    9310     * @throws NullPointerException if an array element is {@code null}
    9311     */
    9312    public static float[] toPrimitive(final Float[] array) {
    9313        if (array == null) {
    9314            return null;
    9315        }
    9316        if (array.length == 0) {
    9317            return EMPTY_FLOAT_ARRAY;
    9318        }
    9319        final float[] result = new float[array.length];
    9320        for (int i = 0; i < array.length; i++) {
    9321            result[i] = array[i].floatValue();
    9322        }
    9323        return result;
    9324    }
    9325
    9326    /**
    9327     * Converts an array of object Floats to primitives handling {@code null}.
    9328     * <p>
    9329     * This method returns {@code null} for a {@code null} input array.
    9330     * </p>
    9331     *
    9332     * @param array  a {@link Float} array, may be {@code null}
    9333     * @param valueForNull  the value to insert if {@code null} found
    9334     * @return a {@code float} array, {@code null} if null array input
    9335     */
    9336    public static float[] toPrimitive(final Float[] array, final float valueForNull) {
    9337        if (array == null) {
    9338            return null;
    9339        }
    9340        if (array.length == 0) {
    9341            return EMPTY_FLOAT_ARRAY;
    9342        }
    9343        final float[] result = new float[array.length];
    9344        for (int i = 0; i < array.length; i++) {
    9345            final Float b = array[i];
    9346            result[i] = b == null ? valueForNull : b.floatValue();
    9347        }
    9348        return result;
    9349    }
    9350
    9351    /**
    9352     * Converts an array of object Integers to primitives.
    9353     * <p>
    9354     * This method returns {@code null} for a {@code null} input array.
    9355     * </p>
    9356     *
    9357     * @param array  a {@link Integer} array, may be {@code null}
    9358     * @return an {@code int} array, {@code null} if null array input
    9359     * @throws NullPointerException if an array element is {@code null}
    9360     */
    9361    public static int[] toPrimitive(final Integer[] array) {
    9362        if (array == null) {
    9363            return null;
    9364        }
    9365        if (array.length == 0) {
    9366            return EMPTY_INT_ARRAY;
    9367        }
    9368        final int[] result = new int[array.length];
    9369        for (int i = 0; i < array.length; i++) {
    9370            result[i] = array[i].intValue();
    9371        }
    9372        return result;
    9373    }
    9374
    9375    /**
    9376     * Converts an array of object Integer to primitives handling {@code null}.
    9377     * <p>
    9378     * This method returns {@code null} for a {@code null} input array.
    9379     * </p>
    9380     *
    9381     * @param array  a {@link Integer} array, may be {@code null}
    9382     * @param valueForNull  the value to insert if {@code null} found
    9383     * @return an {@code int} array, {@code null} if null array input
    9384     */
    9385    public static int[] toPrimitive(final Integer[] array, final int valueForNull) {
    9386        if (array == null) {
    9387            return null;
    9388        }
    9389        if (array.length == 0) {
    9390            return EMPTY_INT_ARRAY;
    9391        }
    9392        final int[] result = new int[array.length];
    9393        for (int i = 0; i < array.length; i++) {
    9394            final Integer b = array[i];
    9395            result[i] = b == null ? valueForNull : b.intValue();
    9396        }
    9397        return result;
    9398    }
    9399
    9400    /**
    9401     * Converts an array of object Longs to primitives.
    9402     * <p>
    9403     * This method returns {@code null} for a {@code null} input array.
    9404     * </p>
    9405     *
    9406     * @param array  a {@link Long} array, may be {@code null}
    9407     * @return a {@code long} array, {@code null} if null array input
    9408     * @throws NullPointerException if an array element is {@code null}
    9409     */
    9410    public static long[] toPrimitive(final Long[] array) {
    9411        if (array == null) {
    9412            return null;
    9413        }
    9414        if (array.length == 0) {
    9415            return EMPTY_LONG_ARRAY;
    9416        }
    9417        final long[] result = new long[array.length];
    9418        for (int i = 0; i < array.length; i++) {
    9419            result[i] = array[i].longValue();
    9420        }
    9421        return result;
    9422    }
    9423
    9424    /**
    9425     * Converts an array of object Long to primitives handling {@code null}.
    9426     * <p>
    9427     * This method returns {@code null} for a {@code null} input array.
    9428     * </p>
    9429     *
    9430     * @param array  a {@link Long} array, may be {@code null}
    9431     * @param valueForNull  the value to insert if {@code null} found
    9432     * @return a {@code long} array, {@code null} if null array input
    9433     */
    9434    public static long[] toPrimitive(final Long[] array, final long valueForNull) {
    9435        if (array == null) {
    9436            return null;
    9437        }
    9438        if (array.length == 0) {
    9439            return EMPTY_LONG_ARRAY;
    9440        }
    9441        final long[] result = new long[array.length];
    9442        for (int i = 0; i < array.length; i++) {
    9443            final Long b = array[i];
    9444            result[i] = b == null ? valueForNull : b.longValue();
    9445        }
    9446        return result;
    9447    }
    9448
    9449    /**
    9450     * Create an array of primitive type from an array of wrapper types.
    9451     * <p>
    9452     * This method returns {@code null} for a {@code null} input array.
    9453     * </p>
    9454     *
    9455     * @param array  an array of wrapper object
    9456     * @return an array of the corresponding primitive type, or the original array
    9457     * @since 3.5
    9458     */
    9459    public static Object toPrimitive(final Object array) {
    9460        if (array == null) {
    9461            return null;
    9462        }
    9463        final Class<?> ct = array.getClass().getComponentType();
    9464        final Class<?> pt = ClassUtils.wrapperToPrimitive(ct);
    9465        if (Boolean.TYPE.equals(pt)) {
    9466            return toPrimitive((Boolean[]) array);
    9467        }
    9468        if (Character.TYPE.equals(pt)) {
    9469            return toPrimitive((Character[]) array);
    9470        }
    9471        if (Byte.TYPE.equals(pt)) {
    9472            return toPrimitive((Byte[]) array);
    9473        }
    9474        if (Integer.TYPE.equals(pt)) {
    9475            return toPrimitive((Integer[]) array);
    9476        }
    9477        if (Long.TYPE.equals(pt)) {
    9478            return toPrimitive((Long[]) array);
    9479        }
    9480        if (Short.TYPE.equals(pt)) {
    9481            return toPrimitive((Short[]) array);
    9482        }
    9483        if (Double.TYPE.equals(pt)) {
    9484            return toPrimitive((Double[]) array);
    9485        }
    9486        if (Float.TYPE.equals(pt)) {
    9487            return toPrimitive((Float[]) array);
    9488        }
    9489        return array;
    9490    }
    9491
    9492    /**
    9493     * Converts an array of object Shorts to primitives.
    9494     * <p>
    9495     * This method returns {@code null} for a {@code null} input array.
    9496     * </p>
    9497     *
    9498     * @param array  a {@link Short} array, may be {@code null}
    9499     * @return a {@code byte} array, {@code null} if null array input
    9500     * @throws NullPointerException if an array element is {@code null}
    9501     */
    9502    public static short[] toPrimitive(final Short[] array) {
    9503        if (array == null) {
    9504            return null;
    9505        }
    9506        if (array.length == 0) {
    9507            return EMPTY_SHORT_ARRAY;
    9508        }
    9509        final short[] result = new short[array.length];
    9510        for (int i = 0; i < array.length; i++) {
    9511            result[i] = array[i].shortValue();
    9512        }
    9513        return result;
    9514    }
    9515
    9516    /**
    9517     * Converts an array of object Short to primitives handling {@code null}.
    9518     * <p>
    9519     * This method returns {@code null} for a {@code null} input array.
    9520     * </p>
    9521     *
    9522     * @param array  a {@link Short} array, may be {@code null}
    9523     * @param valueForNull  the value to insert if {@code null} found
    9524     * @return a {@code byte} array, {@code null} if null array input
    9525     */
    9526    public static short[] toPrimitive(final Short[] array, final short valueForNull) {
    9527        if (array == null) {
    9528            return null;
    9529        }
    9530        if (array.length == 0) {
    9531            return EMPTY_SHORT_ARRAY;
    9532        }
    9533        final short[] result = new short[array.length];
    9534        for (int i = 0; i < array.length; i++) {
    9535            final Short b = array[i];
    9536            result[i] = b == null ? valueForNull : b.shortValue();
    9537        }
    9538        return result;
    9539    }
    9540
    9541    /**
    9542     * Outputs an array as a String, treating {@code null} as an empty array.
    9543     * <p>
    9544     * Multi-dimensional arrays are handled correctly, including
    9545     * multi-dimensional primitive arrays.
    9546     * </p>
    9547     * <p>
    9548     * The format is that of Java source code, for example {@code {a,b}}.
    9549     * </p>
    9550     *
    9551     * @param array  the array to get a toString for, may be {@code null}
    9552     * @return a String representation of the array, '{}' if null array input
    9553     */
    9554    public static String toString(final Object array) {
    9555        return toString(array, "{}");
    9556    }
    9557
    9558    /**
    9559     * Outputs an array as a String handling {@code null}s.
    9560     * <p>
    9561     * Multi-dimensional arrays are handled correctly, including
    9562     * multi-dimensional primitive arrays.
    9563     * </p>
    9564     * <p>
    9565     * The format is that of Java source code, for example {@code {a,b}}.
    9566     * </p>
    9567     *
    9568     * @param array  the array to get a toString for, may be {@code null}
    9569     * @param stringIfNull  the String to return if the array is {@code null}
    9570     * @return a String representation of the array
    9571     */
    9572    public static String toString(final Object array, final String stringIfNull) {
    9573        if (array == null) {
    9574            return stringIfNull;
    9575        }
    9576        return new ToStringBuilder(array, ToStringStyle.SIMPLE_STYLE).append(array).toString();
    9577    }
    9578
    9579    /**
    9580     * Returns an array containing the string representation of each element in the argument array.
    9581     * <p>
    9582     * This method returns {@code null} for a {@code null} input array.
    9583     * </p>
    9584     *
    9585     * @param array the {@code Object[]} to be processed, may be null
    9586     * @return {@code String[]} of the same size as the source with its element's string representation,
    9587     * {@code null} if null array input
    9588     * @throws NullPointerException if an array element is {@code null}
    9589     * @since 3.6
    9590     */
    9591    public static String[] toStringArray(final Object[] array) {
    9592        if (array == null) {
    9593            return null;
    9594        }
    9595        if (array.length == 0) {
    9596            return EMPTY_STRING_ARRAY;
    9597        }
    9598
    9599        final String[] result = new String[array.length];
    9600        for (int i = 0; i < array.length; i++) {
    9601            result[i] = array[i].toString();
    9602        }
    9603
    9604        return result;
    9605    }
    9606
    9607    /**
    9608     * Returns an array containing the string representation of each element in the argument
    9609     * array handling {@code null} elements.
    9610     * <p>
    9611     * This method returns {@code null} for a {@code null} input array.
    9612     * </p>
    9613     *
    9614     * @param array the Object[] to be processed, may be null
    9615     * @param valueForNullElements the value to insert if {@code null} is found
    9616     * @return a {@link String} array, {@code null} if null array input
    9617     * @since 3.6
    9618     */
    9619    public static String[] toStringArray(final Object[] array, final String valueForNullElements) {
    9620        if (null == array) {
    9621            return null;
    9622        }
    9623        if (array.length == 0) {
    9624            return EMPTY_STRING_ARRAY;
    9625        }
    9626
    9627        final String[] result = new String[array.length];
    9628        for (int i = 0; i < array.length; i++) {
    9629            final Object object = array[i];
    9630            result[i] = object == null ? valueForNullElements : object.toString();
    9631        }
    9632
    9633        return result;
    9634    }
    9635
    9636    /**
    9637     * ArrayUtils instances should NOT be constructed in standard programming.
    9638     * Instead, the class should be used as {@code ArrayUtils.clone(new int[] {2})}.
    9639     * <p>
    9640     * This constructor is public to permit tools that require a JavaBean instance
    9641     * to operate.
    9642     * </p>
    9643     */
    9644    public ArrayUtils() {
    9645    }
    9646}