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