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