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