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